Re: [xsl] Nested grouping question

Subject: Re: [xsl] Nested grouping question
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Mon, 05 Jan 2004 11:14:08 -0500
At 2004-01-02 16:29 -0500, Andrew Kirkpatrick wrote:
I've got an XML file organized in one way that I'm trying to convert to
match the organization of other files that I deal with.  I want the file
hierarchy to be:

<game>
    <state>
        <user/>
    </state>
</game>

There are many games, states, and users.

The file that I'm trying to convert is organized by user.  I can do grouping
to determine the states and games, but it seems like I need to do redundant
grouping to do the conversion.  Has anyone does anything similar?  I've got
samples of the input XML and the desired XML below.  Any suggestions are
appreciated...

Because the Meunchian method uses document-wide scope, sometimes it is much easier to use the variable-based grouping methodology with XSLT 1.0 as in the example below. In our hands-on XSL training we cover axis-based, variable-based and key-based grouping methods for XSLT 1.0. With variable-based grouping you can scope your multiple-level groups however you wish and not have to deal with document-wide scope. Note in the example below how I only perform grouping within the previously grouped members.


I hope this helps.

....................... Ken

t:\ftemp>type andrew.xml
<?xml version="1.0" encoding="UTF-8"?>
<report>
    <user>
        <name>Bill</name>
        <state>MT</state>
        <game>Halo</game>
    </user>
    <user>
        <name>Joe</name>
        <state>NJ</state>
        <game>Halo</game>
    </user>
    <user>
        <name>Joe</name>
        <state>NJ</state>
        <game>PGR 2</game>
    </user>
    <user>
        <name>Joe</name>
        <state>MT</state>
        <game>Halo</game>
    </user>
    <user>
        <name>Jim</name>
        <state>AZ</state>
        <game>PGR 2</game>
    </user>
    <user>
        <name>Bill</name>
        <state>IN</state>
        <game>XIII</game>
    </user>
    <user>
        <name>Sue</name>
        <state>IN</state>
        <game>Halo</game>
    </user>
    <user>
        <name>Kim</name>
        <state>AZ</state>
        <game>PGR 2</game>
    </user>
    <user>
        <name>Pat</name>
        <state>AZ</state>
        <game>XIII</game>
    </user>
    <user>
        <name>Ed</name>
        <state>AZ</state>
        <game>PGR 2</game>
    </user>
    <user>
        <name>Neo</name>
        <state>MT</state>
        <game>Halo</game>
    </user>
    <user>
        <name>Mary</name>
        <state>IN</state>
        <game>Halo</game>
    </user>
    <user>
        <name>Jen</name>
        <state>MT</state>
        <game>XIII</game>
    </user>
    <user>
        <name>Thor</name>
        <state>NJ</state>
        <game>XIII</game>
    </user>
</report>

t:\ftemp>type andrew.xsl
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="1.0">

<xsl:output indent="yes"/>

<xsl:template match="/">
  <report>
    <xsl:variable name="games" select="/*/user"/>
    <xsl:for-each select="$games">
      <xsl:if test="generate-id(.)=generate-id($games[game=current()/game])">
        <game title="{game}">
          <xsl:variable name="states" select="$games[game=current()/game]"/>
          <xsl:for-each select="$states">
            <xsl:if test="generate-id(.)=
                          generate-id($states[state=current()/state])">
              <state name="{state}">
                <xsl:for-each select="$states[state=current()/state]">
                  <user name="{name}"/>
                </xsl:for-each>
              </state>
            </xsl:if>
          </xsl:for-each>
        </game>
      </xsl:if>
    </xsl:for-each>
  </report>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>saxon andrew.xml andrew.xsl
<?xml version="1.0" encoding="utf-8"?>
<report>
   <game title="Halo">
      <state name="MT">
         <user name="Bill"/>
         <user name="Joe"/>
         <user name="Neo"/>
      </state>
      <state name="NJ">
         <user name="Joe"/>
      </state>
      <state name="IN">
         <user name="Sue"/>
         <user name="Mary"/>
      </state>
   </game>
   <game title="PGR 2">
      <state name="NJ">
         <user name="Joe"/>
      </state>
      <state name="AZ">
         <user name="Jim"/>
         <user name="Kim"/>
         <user name="Ed"/>
      </state>
   </game>
   <game title="XIII">
      <state name="IN">
         <user name="Bill"/>
      </state>
      <state name="AZ">
         <user name="Pat"/>
      </state>
      <state name="MT">
         <user name="Jen"/>
      </state>
      <state name="NJ">
         <user name="Thor"/>
      </state>
   </game>
</report>


-- North America (Washington, DC): 3-day XSLT/2-day XSL-FO 2004-02-09 Instructor-led on-site corporate, government & user group training for XSLT and XSL-FO world-wide: please contact us for the details

G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0    +1(613)489-0999 (F:-0995)
ISBN 0-13-065196-6                       Definitive XSLT and XPath
ISBN 0-13-140374-5                               Definitive XSL-FO
ISBN 1-894049-08-X   Practical Transformation Using XSLT and XPath
ISBN 1-894049-11-X               Practical Formatting Using XSL-FO
Member of the XML Guild of Practitioners:     http://XMLGuild.info
Male Breast Cancer Awareness  http://www.CraneSoftwrights.com/s/bc


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread