[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Help to unflatten xml file

Subject: Help to unflatten xml file
From: "Steve Ylvisaker" <sylvisaker@xxxxxxxxxxxxxxxxxx>
Date: Tue, 30 Nov 2010 15:43:17 -0600
 Help to unflatten xml file
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

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.