I want to group nodes with same name in Parent tag(<Item>
) as well as in child tag(<Sku>
).
<Item>
tag might contain many <Sku>
child tags but those should not be grouped, rather the elements in every Sku
and Item
should be grouped individually.
I have an input xml file like below:
<Products>
<Item>
<Dimensions>
<Height>10</Height>
</Dimensions>
<Dimensions>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
</Color>
<Color>
<Attribute>Blue</Attribute>
</Color>
<Sku>
<Dimensions>
<Height>10</Height>
</Dimensions>
<Dimensions>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
</Color>
<Color>
<Attribute>Blue</Attribute>
</Color>
</Sku>
<Sku>
<Dimensions>
<Height>10</Height>
</Dimensions>
<Dimensions>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
</Color>
<Color>
<Attribute>Blue</Attribute>
</Color>
</Sku>
</Item>
</Products>
Output expected is like below:
<Products>
<Item>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
<Sku>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
</Sku>
<Sku>
<Dimensions>
<Height>10</Height>
<Weight>10</Weight>
</Dimensions>
<Color>
<Attribute>Orange</Attribute>
<Attribute>Blue</Attribute>
</Color>
</Sku>
</Item>
</Products>
Any help would be greatly appreciated. I have used below xslt to convert but it is only gouping elements present under 'Item'.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="elements" match="Item/*[not(self::Sku)]" use="concat(name(), '|', generate-id(..))"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Item">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:for-each select="*[generate-id() = generate-id(key('elements', concat(name(), '|', generate-id(..)))[1])]">
<xsl:copy>
<xsl:apply-templates select="key('elements', concat(name(), '|', generate-id(..)))/*"/>
</xsl:copy>
</xsl:for-each>
<xsl:apply-templates select="Item" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>