Re: [xsl] Sorting + unique copy problem

Subject: Re: [xsl] Sorting + unique copy problem
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 8 Nov 2001 19:05:38 +0000
Hi Annalisa,

> I tried the code XSL below and the KeyWord values are present in un
> unique copy, but they aren't sorted.

You select every KeyWord element in the document, and then apply
templates to them. The template that matches is the following:

> <xsl:template match="KeyWord">
>     <xsl:for-each select="self::node()[generate-id(.)=generate-id(key('kw',
> .)[1])]">
>     <xsl:sort select="." />
>     <option value="{.}"><xsl:value-of select="."/></option>
>     </xsl:for-each>
> </xsl:template>

The xsl:for-each in the template says 'do the following to this node
if it's the first in the document with its value'. It can only ever
select one node (the KeyWord that you're currently processing) and
will often select no nodes. So there's no list to sort. The content of
this template is the equivalent of:

<xsl:template match="KeyWord">
  <xsl:if test="generate-id() = generate-id(key('kw', .)[1])">
    <option value="{.}"><xsl:value-of select="." /></option>

One way you could fix it is to add an xsl:sort element to the
xsl:apply-templates instruction that's telling the processor to
process the KeyWord elements:

  <xsl:apply-templates select="//KeyWord">
    <xsl:sort select="." />

That way it will process the KeyWord elements in alphabetical order.

In addition, you could make sure that the processor only ever tries to
process keywords that it's actually going to want to do something
with, by changing the xsl:apply-templates so that it selects the
KeyWord elements with a unique value:

      select="//KeyWord[generate-id() = generate-id(key('kw', .)[1])]">
    <xsl:sort select="." />

and then changing the template as it doesn't need to do the test any

<xsl:template match="KeyWord">
  <option value="{.}"><xsl:value-of select="." /></option>

I hope that helps,


Jeni Tennison

 XSL-List info and archive:

Current Thread