[xsl] Displaying a data grid - grouping and using current (not first occurrence) node

Subject: [xsl] Displaying a data grid - grouping and using current (not first occurrence) node
From: "Kevin Daniels" <KevinDaniels@xxxxxxxxxxx>
Date: Tue, 20 Jul 2004 20:20:39 -0400
Hi,

I have some XML where each record node contains a list of test nodes for
which I'm using an xsl:key to group and generate unique values and display
the results in an HTML table where the columns represent the unique test
names and the data is sorted in the grid appropriately.
By checking the key name against a list of the test names in the current
node I can determine which tests exists for the node and what column needs a
value.  Here is some example XML and the XSL I use:

<records>
 <record>
  <id>r0001</id>
  <test id="0001">
   <value>123</value>
   <name>X</name>
  </test>
  <test id="0002">
   <value>456</value>
   <name>B</name>
  </test>
 </record>
 <record>
  <id>r0002</id>
  <test id="0003">
   <value>789</value>
   <name>Y</name>
  </test>
  <test id="0004">
   <value>1</value>
   <name>X</name>
  </test>
 </record>
 <record>
  <id>r0003</id>
  <test id="0005">
   <value>2</value>
   <name>A</name>
  </test>
  <test id="0006">
   <value>3</value>
   <name>Y</name>
  </test>
  <test id="0007">
   <value>45</value>
   <name>X</name>
  </test>
 </record>
 <record>
  <id>r0004</id>
  <test id="0008">
   <value>67</value>
   <name>X</name>
  </test>
  <test id="0009">
   <value>89</value>
   <name>Y</name>
  </test>
 </record>
</records>

<xsl:key name="test-by-name" match="test" use="name"/>

  <xsl:template match="records">
    <html>
      <body>
        <table>
            <tr>
              <th>ID</th>
              <xsl:for-each select="record/test[count(. |
key('test-by-name', name)[1]) = 1]">
                <xsl:sort select="count(key('test-by-name', name))"
data-type="number" order="descending"/>
                <th>
                  <xsl:value-of select="name" />
                </th>
              </xsl:for-each>
            </tr>
            <xsl:for-each select="record">
              <xsl:variable name="current">
                <xsl:for-each select="test">
                  <xsl:value-of select="name"/>|
                </xsl:for-each>
              </xsl:variable>
              <tr>
                <th>
                  <xsl:value-of select="id"/>
                </th>
                <xsl:for-each select="../record/test[count(. |
key('test-by-name', name)[1]) = 1]">
                  <xsl:sort select="count(key('test-by-name', name))"
data-type="number" order="descending"/>
                  <td>
                    <xsl:if test='contains($current, name)'>
                        *<xsl:value-of select="value"/><!--Note that the
value returned is always from the first match of the key-->
                    </xsl:if>
                  </td>
                </xsl:for-each>
              </tr>
            </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>

My problem is that when loopoing over the unique keys, the node returned is
always the first node matching the key, which makes sense, but I need to
return the current node in order to get the correct value into the grid.
I'm looking for something like:

 ID        X    Y    A    B
r0001      123            456
r0002      1    789
r0003      45   3    2
r0004      67   89

Any suggestions?  Any help would be appreciated

Kevin

Current Thread