XSLT a flat list to a tree hierarchy

537 views Asked by At

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.

1

There are 1 answers

0
Martin Honnen On BEST ANSWER

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.