Reputation: 110
I have an XML file which (along with a header) has multiple CC nodes and each CC nodes has multiple child nodes as per below:
<File>
<Header/>
<CC>
<Div>
<SubDiv>
<Com>
<Reg>
<CCOrder>
</CC>
<CC>
<Div>
<SubDiv>
<Com>
<Reg>
<CCOrder>
</CC>
<CC>
<Div>
<SubDiv>
<Com>
<Reg>
<CCOrder>
</CC>
<File>
I want to rearrange/sort the XSLT so that format looks like this (Each child node in CC nodes are grouped together in ascending order):
<File>
<Header/>
<CCDiv>
<Div1>
<Div2>
<Div3>
</CCDiV>
<CCSubDiv>
<SubDiv1>
<SubDiv2>
<SubDiv3>
</CCSubDiv>
<CCCom>
<Com1>
<Com2>
<Com3>
<File>
and so on for Reg and CCOrder nodes.
Can anyone help please?
Upvotes: 0
Views: 64
Reputation: 167716
Assuming XSLT 2 or 3 you can use for-each-group select="CC/*" group-by="node-name(.)"
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="File">
<xsl:copy>
<xsl:for-each-group select="CC/*" group-by="node-name(.)">
<xsl:element name="{local-name(..)}{current-grouping-key()}">
<xsl:apply-templates select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="CC/*">
<xsl:element name="{name()}{position()}"></xsl:element>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/eiZQaG1
Upvotes: 2