Reputation:
I recently ran into a problem I havent found a good solution for yet.
Iam given a XML file with a flat hierarchy and want to transform it into a defined hierarchy.
<xml_file>
<dd/>
<b/>
<b/>
<dd/>
<b/>
<b/>
<dd/>
<k/>
<b/>
<b/>
<dd/>
<b/>
<b/>
</xml_file>
What I want to turn it into:
<xml_file>
<dd>
<b/>
<b/>
</dd>
<dd>
<b/>
<b/>
</dd>
<dd>
<k>
<b/>
<b/>
</k>
</dd>
<dd>
<b/>
<b/>
</dd>
</xml_file>
What would be the best way to do this using xslt 2.0?
Thanks a lot for your help.
Edit:
Sorry. I didnt really explain it well..
Iam given a list of elements thats a are organized by their order in the list.
All b's and k's after a dd are supposed to be children of the preceding dd.
All b's after a k are supposed to be children of the preceding k.
Upvotes: 1
Views: 583
Reputation: 167516
You can use
<xsl:template match="xml_file">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="dd">
<xsl:copy>
<xsl:for-each-group select="current-group() except ." group-starting-with="k">
<xsl:choose>
<xsl:when test="self::k">
<xsl:copy>
<xsl:apply-templates select="current-group() except ."/>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
plus the identity transformation template.
Upvotes: 2