[xsl] multiple level grouping in 2.0

Subject: [xsl] multiple level grouping in 2.0
From: "Goldrick, Jim" <jgoldrick@xxxxxxxxxxxxxxxxx>
Date: Wed, 14 Mar 2007 10:22:19 -0500
Hi all,
I am new to xml/xsl and to this list.  I am trying to do some transformations
for a
reporting web site.  I am using Oxygen and Saxon-8b. Right now my problem is
with mulitple groupings.  I am trying to get output like this in the excel
spreadsheet
(transforming to SpreadSheetML 2003).
2001 | FAL | name | id | course | section # of course |
     |     | name | id | course | section # of course |
     | SPR | name | id | course | section # of course |
     | SPR | name | id | course | section # of course |
2002 | FAL | name | id | course | section # of course |
etc
xml file
<?xml version="1.0" encoding="iso-8859-1"?>
<db name="CRSNO">
<row>
<column type="String" name="fullname">Fullname</column>
<column type="String" name="id">Id</column>
<column type="String" name="yr">Yr</column>
<column type="String" name="sess">Sess</column>
<column type="String" name="crs_no">Crs No</column>
<column type="String" name="sec">Sec</column>
</row>
<row>
<column type="char" name="fullname">Name1, first</column>
<column type="integer" name="id">144915</column>
<column type="smallint" name="yr">2001</column>
<column type="char" name="sess">FAL</column>
<column type="char" name="crs_no">ENG102</column>
<column type="char" name="sec">3</column>
</row>
<row>
<column type="char" name="fullname">Name2, first</column>
<column type="integer" name="id">151479</column>
<column type="smallint" name="yr">2001</column>
<column type="char" name="sess">SPR</column>
<column type="char" name="crs_no">ENG102</column>
<column type="char" name="sec">2</column>
</row>
<row>
<column type="char" name="fullname">Name3, first</column>
<column type="integer" name="id">149659</column>
<column type="smallint" name="yr">2002</column>
<column type="char" name="sess">FAL</column>
<column type="char" name="crs_no">ENG210</column>
<column type="char" name="sec">1</column>
</row>
etc.
It is already sorted.
my xsl, which is not working.  I can get it to output the Year and Session
(2001|FAL)
on every new session, but I would like the year to only output on every new
year.
Also, I would like it to be generic enough that I can use it for any report
that
needs two groups.  Any suggestions would be welcome.
Thanks
Jim
<?xml version="1.0"?>
<!--
This product may incorporate intellectual property owned by Microsoft
Corporation. The terms
and conditions upon which Microsoft is licensing such intellectual property
may be found at
http://msdn.microsoft.com/library/en-us/odcXMLRef/html/odcXMLRefLegalNotice.a
sp.
-->
 <!-- xslt 2.0 for Saxon 8B -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="2.0"
  xmlns="urn:schemas-microsoft-com:office:spreadsheet"
  xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
  <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

  <xsl:param name="grpone">yr</xsl:param>
  <xsl:param name="grptwo">sess</xsl:param>
  <xsl:template match="/">
    <xsl:processing-instruction name="mso-application">
      <xsl:text>progid="Excel.Sheet"</xsl:text>
    </xsl:processing-instruction>
    <xsl:apply-templates select="/db"/>
  </xsl:template>
  <xsl:template match="/db">
    <ss:Workbook>
       <ss:Worksheet>
        <xsl:attribute name="ss:Name">
          <xsl:value-of select="@name"/>
        </xsl:attribute>
        <ss:Table>
          <xsl:for-each-group select="/db/row"
group-by="column[@name=$grpone]">
            <xsl:variable name="gkey1" select="current-grouping-key()"/>
            <xsl:variable name="gpos1" select="position()"/>
            <xsl:for-each-group select="current-group()"
group-by="column[@name=$grptwo]">
              <xsl:variable name="gkey2" select="current-grouping-key()"/>
              <xsl:for-each select="current-group()">
                <xsl:variable name="gpos2" select="position()"/>

                <ss:Row>
                  <ss:Cell>
                    <ss:Data>
                      <xsl:attribute name="ss:Type">
                        <xsl:value-of select="'String'"/>
                      </xsl:attribute>
                      <xsl:choose>
                        <xsl:when test="$gpos1=1">
                          <xsl:value-of select="$gkey1"/>
                        </xsl:when>
                        <xsl:otherwise> </xsl:otherwise>
                      </xsl:choose>
                    </ss:Data>
                  </ss:Cell>
                  <ss:Cell>
                    <ss:Data>
                      <xsl:attribute name="ss:Type">
                        <xsl:value-of select="'String'"/>
                      </xsl:attribute>
                      <xsl:choose>
                        <xsl:when test="$gpos2=1">
                          <xsl:value-of select="$gkey2"/>
                        </xsl:when>
                        <xsl:otherwise> </xsl:otherwise>
                      </xsl:choose>
                    </ss:Data>
                  </ss:Cell>
                  <xsl:for-each select="column">
                    <xsl:if test="./@name != $grpone and ./@name != $grptwo">
                      <ss:Cell>
                        <ss:Data>
                           <xsl:value-of select="normalize-space(.)"/>
                        </ss:Data>
                      </ss:Cell>
                    </xsl:if>
                  </xsl:for-each>
                </ss:Row>
              </xsl:for-each>
            </xsl:for-each-group>
          </xsl:for-each-group>
        </ss:Table>
      </ss:Worksheet>
    </ss:Workbook>
  </xsl:template>
</xsl:stylesheet>

Current Thread