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

Re: [xsl] How to sort a nodeset returned by key()?


Subject: Re: [xsl] How to sort a nodeset returned by key()?
From: "Olivier Mengué" <olivier.mengue@xxxxxxxxx>
Date: Wed, 9 Apr 2008 00:03:33 +0200

2008/4/5, Dolmen ! <dolmen@xxxxxxxxxxx>:
> Michael Kay wrote:
>  > If you are using XSLT 1.0 then the type system only supports node-sets,
not
>  > node-sequences, therefore you cannot store a sorted node-sequence in a
>  > variable.
>  >
>  > The approach you outline would be fine for XSLT 2.0, but in 1.0 you'll
have
>  > to find some other way.
>
>
> I found an other way. However it is much more verbose and it requires an
additional for-each loop.

Here is the missing code :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
omit-xml-declaration="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:key name="accounts-by-region" match="/demo/salesman/account"
use="@region"/>

  <xsl:template match="/demo">
    <html>
    <head><title>Accounts ordered by region</title></head>
      <body>
        <table border="1">
          <tr><th>Region</th><th>Account</th></tr>
          <xsl:for-each select="salesman/account[count( . |
key('accounts-by-region', @region)[1]) = 1]">
            <xsl:sort select="@region"/>

            <xsl:variable name="region" select="@region"/>
            <xsl:variable name="accounts"
select="key('accounts-by-region', $region)"/>

            <xsl:for-each select="$accounts">
              <xsl:sort select="."/>
              <tr>
                <xsl:if test="position() = 1">
                  <xsl:variable name="rowspan" select="count($accounts)"/>
                  <td><xsl:if test="$rowspan &gt; 1"><xsl:attribute
name="rowspan"><xsl:value-of
select="$rowspan"/></xsl:attribute></xsl:if><xsl:value-of
select="$region"/></td>
                </xsl:if>
                <td><xsl:value-of select="."/></td>
              </tr>
            </xsl:for-each>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>

</xsl:stylesheet>

Olivier Mengui
http://o.mengue.free.fr/


Current Thread
Keywords