Wrox Programmer Forums
Go Back   Wrox Programmer Forums > XML > XSLT
|
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old November 3rd, 2003, 08:29 AM
Registered User
 
Join Date: Nov 2003
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default reorder nodes problem

Hello there,
I have the following problem:
I have a list like
<Parent>
  <ELEMENT name="aaa" attr="bad"></ELEMENT>
  <ELEMENT name="bbb" attr="bad"></ELEMENT>
  <ELEMENT name="ccc"></ELEMENT>
  <ELEMENT name="ddd"></ELEMENT>
  <ELEMENT name="eee"></ELEMENT>
 ...
</Parent>
I want to reorder them into this:
<NewPar>
  <ELEMENT name="ccc"></ELEMENT>
  <ELEMENT name="ddd"></ELEMENT>
</NewPar>
<NewPar>
  <ELEMENT name="eee"></ELEMENT>
 ...
</NewPar>
...

This means leaving out the two bad ones, and putting every two of the following ones into a new Tag.
I am new to XSLT and I although I tried hard I have no idea how to get along without any suitable counters or something like that.

Thank you for your help.
Tony
 
Old November 3rd, 2003, 09:20 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

Try this, it uses the mod operator to see whether to start a new group and adds a new document element.
Code:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes"/>  
  <xsl:template match="/">
    <data>
      <xsl:apply-templates select="Parent/ELEMENT[not(@attr = 'bad')]"/>
    </data>
  </xsl:template>
  <xsl:template match="ELEMENT">    
    <xsl:if test="position() mod 2 = 1">
      <newParent>
        <xsl:copy-of select="."/>
        <xsl:copy-of select="following-sibling::*[not(@attr = 'bad')][1]"/>
      </newParent>     
    </xsl:if>
  </xsl:template>  
</xsl:stylesheet>
Joe (MVP - xml)
 
Old November 3rd, 2003, 10:19 AM
Registered User
 
Join Date: Nov 2003
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Wow, thank you for that quick answer.
I see there is a lot to learn for me and I'll carefully analyze your examples.

Mangling your code into my stylesheet I came across a little follow-up problem:
'Elements' are formatted. I call the formatting with
<xsl:call-template name="format_name">.
So i changed

<xsl:if test="position() mod 2 = 1">
 <newParent>
   <xsl:copy-of select="."/>
   <xsl:copy-of select="following-sibling::*[not(@attr = 'bad')][1]"/>
  </newParent>
</xsl:if>

to

<xsl:if test="position() mod 2 = 1">
 <newParent>
   <xsl:call-template name="format_name"> <--
   <xsl:copy-of select="following-sibling::*[not(@attr = 'bad')][1]"/>
  </newParent>
</xsl:if>

but don't know how to pass the actual sibling of 'following-sibling...' to 'call-template'. The respective first element is already formatted well.

Any further clue for me?

Thank you for your answer anyway.
tony

 
Old November 3rd, 2003, 05:34 PM
Registered User
 
Join Date: Nov 2003
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

did my homework meanwhile...:)
for documentation, it works like this (think there's a shorter way)

...
<newParent>
  <xsl:call-template name="format_name">
  <xsl:for-each select="following-sibling::*[1]"/>
    <xsl:call-template name="format_name">
  </xsl:for-each>
</newParent>
...

hope it helps someone else,
tony

 
Old November 5th, 2003, 09:02 AM
joefawcett's Avatar
Wrox Author
 
Join Date: Jun 2003
Posts: 3,074
Thanks: 1
Thanked 38 Times in 37 Posts
Default

That's ok, as long as all your "bad" elemenets are at the beginning. You could also try using parameters, that way your "format_name" template does not have to rely on using the current node:
Code:
<xsl:template name="format_name">
  <xsl:param name="current" select="."/>

</xsl:template>
Called by:
Code:
<xsl:call-template name="format_name">
  <xsl:with-param select="."/>
</xsl:call-template>
<xsl:call-template name="format_name">
  <xsl:with-param select="following-sibling::*[not(@attr = 'bad')][1]"/>
</xsl:call-template>
If you don't pass a parameter the current node will be used.

Joe (MVP - xml)

--

Joe





Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem Copying Nodes tclotworthy XSLT 14 February 13th, 2007 01:13 PM
How to reorder the auto number column? al-hijjawi SQL Server 2000 3 April 28th, 2006 07:37 PM
Nodes ....'For Each' problem. Neal XSLT 3 February 13th, 2006 08:57 AM
Reorder columns in DataSet filipczako C# 3 November 29th, 2005 10:29 AM
REORDER LEVEL TRIGGER jemacc SQL Server 2000 3 April 20th, 2004 12:30 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.