[xsl] Help to unflatten xml file

Subject: [xsl] Help to unflatten xml file
From: "Steve Ylvisaker" <sylvisaker@xxxxxxxxxxxxxxxxxx>
Date: Tue, 30 Nov 2010 15:43:17 -0600
I want to nest sections from a flat XML file based on the value of a section
attribute. I have done this before with a similar but slightly different
situation. I'm missing something with the behavior of xsl:for-each-group.

Thanks in advance for any help that can be provided.
Steve

My example data:

<?xml version="1.0" encoding="UTF-8"?>
<book type="Tech_Manual">
    <bookinfo>
        <title>client manual</title>
        <subtitle>performance data</subtitle>
    </bookinfo>
    <section id="a--21" label="1">
        <title lang="en">Preface</title>
        <para>some interesting stuff</para>
    </section>
    <section id="a--22" label="2">
        <title lang="en">Preface</title>
        <para>some more interesting stuff</para>
    </section>
    <section id="a--23" label="2">
        <title lang="en">Preface</title>
        <para>some more interesting stuff</para>
    </section>
    <section id="a--24" label="3">
        <title lang="en">Preface</title>
        <para>some more interesting stuff</para>
    </section>
    <section id="a--25" label="1">
        <title lang="en">Cautions</title>
        <para>some interesting stuff</para>
    </section>
</book>

My stylesheet:
<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xs="http://www.w3.org/2001/XMLSchema";>


    <xsl:output
        method="xml"
        omit-xml-declaration="no"
        encoding="utf-8"
        indent="yes"/>
    <xsl:strip-space elements="*"/>


<!-- Pass one - recognize section headers and create nested <sections/> -->
   <xsl:template match="/">
       <xsl:variable name="unflattenedDoc">
           <book>
              <xsl:copy>
                <xsl:for-each-group select="*"
group-starting-with="section[@label=1]">
                  <xsl:apply-templates select="." mode="group"/>
                </xsl:for-each-group>
              </xsl:copy>
          </book>
       </xsl:variable>
       <xsl:apply-templates select="$unflattenedDoc" mode="pass2"/>
   </xsl:template>

  <xsl:template match="section[@label=1]" mode="group">
    <section>
        <xsl:for-each-group select="current-group()"
group-starting-with="section[@label=2]">
            <xsl:apply-templates select="." mode="group"/>
        </xsl:for-each-group>
    </section>
  </xsl:template>

  <xsl:template match="section[@label=2]" mode="group">
    <section>
        <xsl:for-each-group select="current-group()"
group-starting-with="section[@label=3]">
            <xsl:apply-templates select="." mode="group"/>
        </xsl:for-each-group>
    </section>
  </xsl:template>

  <xsl:template match="section[@label=3]" mode="group">
     <section>
         <xsl:copy-of select="current-group()"/>
     </section>
  </xsl:template>


<xsl:template match="node()" mode="group">
    <xsl:copy-of select="current-group()"/> </xsl:template>


  <!-- 2nd pass -->
    <xsl:template match="book" mode="pass2">
        <xsl:copy-of select="."/>
    </xsl:template>

</xsl:stylesheet>

My desired result:

<book type="Tech_Manual">
    <bookinfo>
        <title>client manual</title>
        <subtitle>performance data</subtitle>
    </bookinfo>
    <section id="a--21" label="1">
        <title lang="en">Preface</title>
        <para>some interesting stuff</para>

    <section id="a--22" label="2">
        <title lang="en">Preface</title>
        <para>some more interesting stuff</para>
    </section>
    <section id="a--23" label="2">
        <title lang="en">Preface</title>
        <para>some more interesting stuff</para>

    <section id="a--24" label="3">
        <title lang="en">Preface</title>
        <para>some more interesting stuff</para>
    </section>
    </section>
    </section>
    <section id="a--25" label="1">
        <title lang="en">Cautions</title>
        <para>some interesting stuff</para>
    </section>
</book>

My actual result:

<book xmlns:xs="http://www.w3.org/2001/XMLSchema";>
   <book type="Tech_Manual">
      <bookinfo>
         <title>client manual</title>
         <subtitle>performance data</subtitle>
      </bookinfo>
      <section id="a--21" label="1">
         <title lang="en">Preface</title>
         <para>some interesting stuff</para>
      </section>
      <section id="a--22" label="2">
         <title lang="en">Preface</title>
         <para>some more interesting stuff</para>
      </section>
      <section id="a--23" label="2">
         <title lang="en">Preface</title>
         <para>some more interesting stuff</para>
      </section>
      <section id="a--24" label="3">
         <title lang="en">Preface</title>
         <para>some more interesting stuff</para>
      </section>
      <section id="a--25" label="1">
         <title lang="en">Cautions</title>
         <para>some interesting stuff</para>
      </section>
   </book>
</book>

Current Thread