Re: A specific Transformation quesition

Subject: Re: A specific Transformation quesition
From: "Steve Muench" <Steve.Muench@xxxxxxxxxx>
Date: Thu, 26 Oct 2000 19:28:21 -0700
Adam,

| I need some help figuring out how to do a somewhat complex transform (XML
| into HTML) that I need help with. Its essentially a cross-tab type
| situation.

Here's a stylesheet that produces the cross-product
you're looking for. It uses an <xsl:key> like functional
indexes to speed up the iteration of unique regions.

Assuming the input is:

<demo>
  <salesman id="0001" name="Rick Peterson">
    <account id="act001" region="Midwest">Johnosn's Laundry</account>
    <account id="act002" region="Canada">Franks's Laundry</account>
    <account id="act003" region="Alaska">Mary's Laundry</account>
    <account id="act004" region="New Jersey">Bill's Laundry</account>
    <account id="act005" region="Midwest">Hammond's Laundry</account>
  </salesman> 
  <salesman id="0003" name="Ty Coon">
    <account id="act006" region="Canada">Franks's Diner</account>
    <account id="act007" region="Midwest">Johnosn's Diner</account>
    <account id="act008" region="Canada">Hammond's Diner</account>
    <account id="act009" region="Alaska">Mary's Diner</account>
    <account id="act010" region="Alaska">Bill's Diner</account>
  </salesman> 
</demo>

The following stylesheet produces an HTML table crosstab
with salespeople down the left (ordered by name) and regions
across the top (ordered by name), with a grid cell for each
crosstab, and &nsbp; for empty cells.

<!-- Example of a "CrossTab" stylesheet using <xsl:key>'s for grouping -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:key name="b" match="@region" use="."/>
  <xsl:template match="/">
    <html>  
      <body>
        <table border="1" cellspacing="0">
          <!-- Generate the row of table header cells -->
          <tr>
            <th>Salesperson</th>
            <!-- 
             | Generate a header cell for each unique region name
             |
             | See Chapter 9 of "Building Oracle XML Applications" from O'Reilly
             | for a detailed explanation of how this <xsl:key> based technique works
             +-->
            <xsl:for-each select="//@region[generate-id(.)=generate-id(key('b',.)[1])]">
              <!-- Sort by the region name (the value of the current @region attribute -->
              <xsl:sort select="."/>
              <th>
                <xsl:value-of select="."/>
              </th>
            </xsl:for-each>
          </tr>
        <!-- Generate a row for each salesman -->
        <xsl:for-each select="demo/salesman">
          <!-- Sort by salesman name -->
          <xsl:sort select="@name"/>
          <!-- Keep the current salesman in a variable for later -->
          <xsl:variable name="cur" select="."/>
          <tr>
            <!-- First cell has the salesman's name -->
            <td bgcolor="yellow"><xsl:value-of select="@name"/></td>
            <!-- Generate a cell for each unique region -->
            <xsl:for-each select="//@region[generate-id(.)=generate-id(key('b',.)[1])]">
              <td>
                <!-- If no accts for current salesman in current region, do &nbsp; -->
                <xsl:if test="not($cur/account[@region=current()])">&#160;</xsl:if>
                <!-- List matching accounts for current salesman in current region -->
                <xsl:for-each select="$cur/account[@region=current()]">
                  <xsl:value-of select="."/>
                  <xsl:if test="position() != last()"><br/></xsl:if>
                </xsl:for-each>
              </td>
            </xsl:for-each>
          </tr>
        </xsl:for-each>
      </table>
    </body>
  </html>
  </xsl:template>
</xsl:stylesheet>
______________________________________________________________
Steve Muench, Lead XML Evangelist & Consulting Product Manager
BC4J & XSQL Servlet Development Teams, Oracle Rep to XSL WG
Author "Building Oracle XML Applications", O'Reilly
http://www.oreilly.com/catalog/orxmlapp/



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


Current Thread