Re: [xsl] xsl:sort ... jeff comes before Jeff?

Subject: Re: [xsl] xsl:sort ... jeff comes before Jeff?
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Wed, 16 Oct 2002 17:44:14 +0100
Hi Roger,

> Suppose that I use xsl:sort to sort these two names:  jeff  and Jeff
> I ran some tests.  Here are the results:
> xalan, xt, and msxml all sort the names as:
> jeff
> Jeff
> saxon sorts the names as:
> Jeff
> jeff
> Who's right?

Both, in a way. The attribute that governs the order in which the
cases are sorted is case-order; the XSLT spec says:

  case-order has the value upper-first or lower-first; this applies
  when data-type="text", and specifies that upper-case letters should
  sort before lower-case letters or vice-versa respectively. For
  example, if lang="en", then A a B b are sorted with
  case-order="upper-first" and a A b B are sorted with
  case-order="lower-first". The default value is language dependent.

I guess that Saxon thinks that the language that you're using for your
system environment should be sorted with capitals before lowercase
letters, whereas the others disagree. I'm not sure whether we can say
which one's right. Anyway, if you care -- if you want to force a
particular order -- use the case-order attribute to say which ordering
you want.
> Consider the following xslt which redefines a variable, names,
> several times:
> <xsl:variable name="names" select="/FitnessCenter/Member[1]/Name"/>
> <xsl:for-each select="/FitnessCenter/Member[position() &gt; 1]">
>              <xsl:variable name="names" select="concat($names, '/')"/>
>               <xsl:variable name="names" select="concat($names, Name)"/>
>  </xsl:for-each>
> <xsl:value-of select="$names"/>
> xalan and xt have no problems with it.
> saxon generates two error messages - saying that name has been redclared.
> Who's right?

Saxon is right. The XSLT Rec. says:

  A [variable] binding shadows another binding if the binding occurs
  at a point where the other binding is visible, and the bindings have
  the same name. It is an error if a binding established by an
  xsl:variable or xsl:param element within a template shadows another
  binding established by an xsl:variable or xsl:param element also
  within the template.

Variables in XSLT (and other declarative languages) are not the same
as variables in Java or C (or other procedural languages). You can't
"redefine" or "update" or "change" variables in XSLT. Theoretically,
your code is perfectly reasonable, but when you do:

  <xsl:value-of select="$names" />

at the end, the only $names variable that's in scope at that point is
the original one:

  <xsl:variable name="names" select="/FitnessCenter/Member[1]/Name"/>

XSLT 1.0 makes variable "redefinitions" an error to indicate that the
$names variable is not being changed or updated within the
<xsl:for-each> -- for all intents and purposes, those variable
definitions would be for *new* variables.


Jeni Tennison

 XSL-List info and archive:

Current Thread