Click to See Complete Forum and Search --> : Simple XSLT grouping
mcgoo
05-19-2008, 04:01 PM
sorry for the simplicity of this question but I'm new to this... I want to do a simple transform where just copy the original document but group some of the child nodes under a common parent (called 'subchildren' in this example) in the output, basically:
From this:
<root>
<child>
<sub>Value1</sub>
<sub>Value2</sub>
<sub>Value3</sub>
</child>
<child>
<sub>Value4</sub>
<sub>Value5</sub>
<sub>Value6</sub>
</child>
</root>
To this:
<root>
<child>
<subchildren>
<sub>Value1</sub>
<sub>Value2</sub>
<sub>Value3</sub>
</subchildren>
</child>
<child>
<subchildren>
<sub>Value4</sub>
<sub>Value5</sub>
<sub>Value6</sub>
</subchildren>
</child>
</root>
whats the best way to accomplish this? thank you in advance
rpgfan3233
05-19-2008, 04:37 PM
Well, root and child are pretty straightforward. As for subchildren, you just add an element if there are sub elements that are children of child elements:
<?xml version="1.0" encoding="utf-8"?>
<xsl:template match="/">
<xsl:element name="root">
<xsl:for-each select="root/child">
<xsl:element name="child">
<xsl:if test="name(*) = 'sub'">
<xsl:element name="subchildren">
<xsl:for-each select="sub">
<xsl:element name="sub">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
mcgoo
05-19-2008, 05:12 PM
hmm, its looks like this part isn't correct for what I'm trying to do:
<xsl:if test="name(*) = 'sub'">
<xsl:element name="subchildren">
<xsl:for-each select="sub">
<xsl:element name="sub">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:if>
maybe i should have given more details, because it worked with the example I provided, but I should have been more specific. The <subs> nodes aren't the only children of <child> they're just the ones I want to group. In reality it looks more like this:
<root>
<child>
<element1>avalue</element1>
<element2>anothervalue</element2>
<element3>yetanothervalue</element3>
<sub>Value1</sub>
<sub>Value2</sub>
<sub>Value3</sub>
</child>
<child>
<element1>avalue2</element1>
<element2>anothervalue2</element2>
<element3>yetanothervalue2</element3>
<sub>Value4</sub>
<sub>Value5</sub>
<sub>Value6</sub>
</child>
</root>
rpgfan3233
05-19-2008, 06:02 PM
<xsl:template match="/">
<xsl:element name="root">
<xsl:for-each select="root/child">
<xsl:element name="child">
<xsl:for-each select="*[name(.) != 'sub']">
<xsl:copy-of select="."/>
</xsl:for-each>
<xsl:element name="subchildren">
<xsl:for-each select="*[name(.) = 'sub']">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
That one should work better for you. ^_^
mcgoo
05-19-2008, 08:27 PM
yes that does it! thank you for your help.