The input file format is
<Node1 Attribute11="colors" >
<Node2 Attribute21="Order1" Attribute22="123" Attribute23="red" />
<Node2 Attribute21="Order2" Attribute22="456" Attribute23="blue" />
<Node2 Attribute21="Order1" Attribute22="789" Attribute23="green" />
<Node2 Attribute21="Order2" Attribute22="012" Attribute23="yellow" />
<Node2 Attribute21="Order3" Attribute22="345" Attribute23="red" />
<Node2 Attribute21="Order1" Attribute22="678" Attribute23="blue" />
</Node1>
The desired output is
<Node1 Attribute11="colors" >
<Node3 Attribute21="Order1" >
<Node2 Attribute21="Order1" Attribute22="123" Attribute23="red" />
<Node2 Attribute21="Order1" Attribute22="789" Attribute23="green" />
<Node2 Attribute21="Order1" Attribute22="678" Attribute2开发者_JAVA百科3="blue" />
</Node3>
<Node3 Attribute21="Order2">
<Node2 Attribute21="Order2" Attribute22="456" Attribute23="blue" />
<Node2 Attribute21="Order2" Attribute22="012" Attribute23="yellow" />
</Node3>
<Node3 Attribute21="Order3">
<Node2 Attribute21="Order3" Attribute22="345" Attribute23="red" />
</Node3>
</Node1>
With the grouping I am not able to get the output in the desired format. Any help with XSLT 1.0 is much appreciated
XSLT 1.0 solutions tested with Saxon-HE 9.2.1.1
Solution with looping:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="byAttribute21" match="Node1/Node2" use="@Attribute21"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Node1">
<Node1>
<xsl:copy-of select="@*"/>
<xsl:for-each select="Node2[generate-id()=generate-id(key('byAttribute21', @Attribute21)[1])]">
<Node3 Attribute21="{@Attribute21}">
<xsl:apply-templates select="key('byAttribute21', @Attribute21)"/>
</Node3>
</xsl:for-each>
</Node1>
</xsl:template>
</xsl:stylesheet>
Solution without looping:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="byAttribute21" match="Node1/Node2" use="@Attribute21"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Node1">
<Node1>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="*" mode="node3"/>
</Node1>
</xsl:template>
<xsl:template match="Node2[generate-id()=generate-id(key('byAttribute21', @Attribute21)[1])]" mode="node3">
<Node3 Attribute21="{@Attribute21}">
<xsl:apply-templates select="key('byAttribute21',@Attribute21)" mode="node2"/>
</Node3>
</xsl:template>
<xsl:template match="Node2" mode="node2">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
精彩评论