I have a flat xml file that needs to be converted to hierarchical. I used the nested grouping idea from here xsl:for-each-group help needed. It's working for the most part except for a couple of issues:
1) The elements root1 and root2 are not showing up.
2) The location of element level21 is incorrect. The first level21 with sequencecount=2 should be between the 2 level2 elements.
Any help is really appreciated.
Thanks.
Source XML
<root>
<root1>1234</root1>
<root2>5678</root2>
<level1>
<a>line 1</a>
<b>line 2</b>
<c>line 3</c>
</level1>
<level2>
<d>line 4</d>
<e>line 5</e>
<f>line 6</f>
<g>line 7</g>
</level2>
<level3>
<h>line 8</h>
<i>line 9</i>
<j>line 10</j>
<k>line 11</k>
<l>line 12</l>
</level3>
<level4>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
<level4>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
<level21>
<d>line 214</d>
<e>line 215</e>
<f>line 216</f>
<g>line 217</g>
</level21>
<level2>
<d>line 19</d>
<e>line 20</e>
<f>line 21</f>
<g>line 22</g>
</level2>
<level3>
<h>line 23</h>
<i>line 24</i>
<j>line 25</j>
<k>line 26</k>
<l>line 27</l>
</level3>
<level4>
<m>line 28</m>
<n>line 29</n>
<o>line 30</o>
</level4>
<level4>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
<level21>
<d>line 224</d>
<e>line 225</e>
<f>line 226</f>
<g>line 227</g>
</level21>
Required Result XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<root1>1234</root1>
<root2>5678</root2>
<level1>
<a>line 1</a>
<b>line 2</b>
<c>line 3</c>
<level2>
<d>line 4</d>
<e>line 5</e>
<f>line 6</f>
<g>line 7</g>
<level3>
<SequenceCount>1</SequenceCount>
<h>line 8</h>
<i>line 9</i>
<j>line 10</j>
<k>line 11</k>
<l>line 12</l>
<level4>
<SequenceCount>1</SequenceCount>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
<level4>
<SequenceCount>2</SequenceCount>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
</level3>
</level2>
<level21>
<SequenceCount>2</SequenceCount>
<d>line 214</d>
<e>line 215</e>
<f>line 216</f>
<g>line 217</g>
</level21>
<level2>
<d>line 19</d>
<e>line 20</e>
<f>line 21</f>
<g>line 22</g>
<level3>
<SequenceCount>3</SequenceCount>
<h>line 23</h>
<i>line 24</i>
<j>line 25</j>
<k>line 26</k>
<l>line 27</l>
<level4>
<SequenceCount>1</SequenceCount>
<m>line 28</m>
<n>line 29</n>
<o>line 30</o>
</level4>
<level4>
<SequenceCount>2</SequenceCount>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
</level3>
</level2>
<level21>
<SequenceCount>4</SequenceCount>
<d>line 224</d>
<e>line 225</e>
<f>line 226</f>
<g>line 227</g>
</level21>
</level1>
</root>
My XSL
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="fn" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0"
exclude-result-prefixes="xs fn">
<xsl:output indent="yes" />
<xsl:template match="/">
<xsl:for-each-group select="*" group-starting-with="root">
<root>
<xsl:for-each-group select="*" group-starting-with="*[name(.)='level1']">
<xsl:choose>
<xsl:when test="name(.)='level1'">
<level1>
<xsl:apply-templates />
<xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='level2']">
<xsl:choose>
<xsl:when test="name(.)='level2'">
<level2>
<xsl:apply-templates />
<xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='level3']">
<xsl:choose>
<xsl:when test="name(.)='level3'">
<level3>
<xsl:element name="SequenceCount"><xsl:number count="level3|level21" level="any"/></xsl:element>
<xsl:apply-templates />
<xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='level4']">
<xsl:choose>
<xsl:when test="name(.)='level4'">
<level4>
<xsl:element name="SequenceCount"><xsl:number value="position() - 1"/></xsl:element>
<xsl:apply-templates />
</level4>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
</level3>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
</level2>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
<xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='level21']">
<xsl:choose>
<xsl:when test="name(.)='level21'">
<level21>
<xsl:element name="SequenceCount"><xsl:number count="level3|level21" level="any"/></xsl:element>
<xsl:apply-templates />
</level21>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
</level1>
</xsl:when>
</xsl:choose>
</xsl:for-each-group>
</root>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Current Output XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<level1>
<a>line 1</a>
<b>line 2</b>
<c>line 3</c>
<level2>
<d>line 4</d>
<e>line 5</e>
<f>line 6</f>
<g>line 7</g>
<level3>
<SequenceCount>1</SequenceCount>
<h>line 8</h>
<i>line 9</i>
<j>line 10</j>
<k>line 11</k>
<l>line 12</l>
<level4>
<SequenceCount>1</SequenceCount>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
<level4>
<SequenceCount>2</SequenceCount>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
</level3>
</level2>
<level2>
<d>line 19</d>
<e>line 20</e>
<f>line 21</f>
<g>line 22</g>
<level3>
<SequenceCount>3</SequenceCount>
<h>line 23</h>
<i>line 24</i>
<j>line 25</j>
<k>line 26</k>
<l>line 27</l>
<level4>
<SequenceCount>1</SequenceCount>
<m>line 28</m>
<n>line 29</n>
<o>line 30</o>
</level4>
<level4>
<SequenceCount>2</SequenceCount>
<m>line 13</m>
<n>line 14</n>
<o>line 15</o>
</level4>
</level3>
</level2>
<level21>
<SequenceCount>2</SequenceCount>
<d>line 214</d>
<e>line 215</e>
<f>line 216</f>
<g>line 217</g>
</level21>
<level21>
<SequenceCount>4</SequenceCount>
<d>line 224</d>
<e>line 225</e>
<f>line 226</f>
<g>line 227</g>
</level21>
</level1>
</root>