RE: [xsl] flatened hiearchies for xslt2

Subject: RE: [xsl] flatened hiearchies for xslt2
From: "Patrick Lachance" <plachance@xxxxxxxxx>
Date: Wed, 7 Mar 2007 12:37:49 -0500
I think something like that should do the job:

<xsl:template match="section">
    <section id={@id}>
        <xsl:call-template name="makeLevel"/>
    </section>
</xsl:template>
<xsl:template name="makeLevel">
    <xsl:param name="level" as="xs:integer" select="1"/>
    <xsl:variable name="nextLevel" as="xs:integer" select="$level+1"/>
    <xsl:variable name="parentId" select="@id"/>
    <section id={@id}>
        <xsl:for-each select="section/*[@level=$nextLevel and
starts-with(@id,$parentId)]>
            <xsl:call-template name="makeLevel">
                <xsl:with-param name="level" select="$nextLevel"/>
            </xsl:call-template>
        </xsl:for-each>
    </section>
</xsl:template>

-----Original Message-----
From: ac [mailto:ac@xxxxxxxxxxxxx]
Sent: Wednesday, March 07, 2007 12:12 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
Subject: [xsl] flatened hiearchies for xslt2

Hi,

I love functional programming, XSLT2, and Saxon.

I recently faced what first seemed like a simple case, yet it got me
scratching my head for a while, before figuring a workaround for the
real-life problem at hand.  Still it seems so simple that there must be
cleaner way ...

If the following recursive logical XML structure
      <section id="logical">
         <section id="1">
             <section id="1-1"/>
             <section id="1-2">
                 <section id="1-2-1"/>
                 <section id="1-2-2"/>
             </section>
         </section>
         <section id="2">
         </section>
     </section>

can easily be transformed to its flattened equivalent, like:
     <section id="flat">
         <section id="1" level="1"/>
         <section id="1-1" level="2"/>
         <section id="1-2" level="2"/>
         <section id="1-2-1" level="3"/>
         <section id="1-2-2" level="3"/>
         <section id="2" level="1"/>
     </section>
where the @level attribute represents the "indent" or embedding level.

My question is:
What is the best approach to transform the "flat" structure back to the
original logical structure, with XSLT2 (Saxon), assuming that only the
'flat' version is received by the application?

At first, it is easy to sequentially read and rebuild the sections,
- recursing further when @level increments (embedded sections)
- iterating further when @level remains the same (sibling sections)

But the remaining issue is to manage exit from the recursion, as @levels
come back down.
In the example,  from section 1-2-2 to section 2 (level 3 to level 1).

Note that section ids are hierarchical here only for clarity as in
reality they would be anything.

There must be a 'clean' solution to this relatively common/simple
transformation issue.
Any help or guidance would be appreciated.

Thank you
ac

Current Thread