[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] XML grouping/sorting question - displaying a matrix


Subject: RE: [xsl] XML grouping/sorting question - displaying a matrix
From: <Jarno.Elovirta@xxxxxxxxx>
Date: Tue, 30 Mar 2004 10:26:56 +0300

Hi,

> Finally, I would ultimately like to sort the columns in the 
> above matrix by
> element count so that the elements which appear most are in the first
> columns, though I haven't found a way to do this:
> 
> ID        X    C    B    Y
> 0001      *         *
> 0002      *              *
> 0003      *    *
> 0004      *    *

  <xsl:key name="test-by-name" match="test" use="name"/>
  <xsl:template match="records">
    <html>
      <body>
        <table>
          <thead>
            <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>
          </thead>
          <tbody>
            <xsl:for-each select="record/test">
              <xsl:variable name="current" select="name"/>
              <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="name = $current">*</xsl:if>
                  </td>
                </xsl:for-each>
              </tr>
            </xsl:for-each>
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>

or, if can use ext:node-set

  <xsl:template match="records" xmlns:exsl="http://exslt.org/common">
    <html>
      <body>
        <table>
          <xsl:variable name="columns-rtf">
            <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"/>
              <xsl:copy-of select="name" />
            </xsl:for-each>
          </xsl:variable>
          <xsl:variable name="columns" select="exsl:node-set($columns-rtf)/name"/>
          <thead>
            <tr>
              <th>ID</th>
              <xsl:for-each select="$columns">
                <th>
                  <xsl:value-of select="." />
                </th>
              </xsl:for-each>
            </tr>
          </thead>
          <tbody>
            <xsl:for-each select="record/test">
              <xsl:variable name="current" select="name"/>
              <tr>
                <th>
                  <xsl:value-of select="@id"/>
                </th>
                <xsl:for-each select="$columns">
                  <td>
                    <xsl:if test=". = $current">*</xsl:if>
                  </td>
                </xsl:for-each>
              </tr>
            </xsl:for-each>
          </tbody>
        </table>
      </body>
    </html>
  </xsl:template>

or you could create a space separated list of column names and go through that with a recursive template.

Cheers,

Jarno


Current Thread