Re: [xsl] having trouble with xsl:choose and xsl:sort

Subject: Re: [xsl] having trouble with xsl:choose and xsl:sort
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Sat, 4 Jan 2003 23:29:40 -0800 (PST)
"Cox, Todd (NIH/NCI)" <tcox@xxxxxxxxxxxx> wrote in message
news:27C204BD76CBC142BA1AE46D62A8548ECF5436@xxxxxxxxxxxxxxxxxxxxxxx
> Hello All,
> 
> I am tring to provide sorting a sorting capability using parameters
as my
> selecting process. I am using Cocoon and when I try to use a
<xsl:choose>
> and select a <xsl:sort> I get a Can't have a <xsl:sort> in a
<xsl:choose>.
> The the stylesheet is as follows:

xsl:sort cannot be a child of xsl:when. It can only be a child of
either xsl:for-each or xsl:apply-templates.

According to the XSLT 1.0 spec:

"Sorting is specified by adding xsl:sort elements as children of an
xsl:apply-templates or xsl:for-each element."

http://www.w3.org/TR/xslt#sorting

What you want to do can be accomplished in the following way:

Let's have the following source.xml (you didn't provide one):

<t>
  <measure>
    <note print-spacing="no">a</note>
    <note print-spacing="no">b</note>
  </measure>
  <measure>
    <note print-spacing="no">a</note>
    <note>b</note>
  </measure>
  <measure>
    <note print-spacing="no">a</note>
    <note print-spacing="yes">b</note>
  </measure>
  <measure>
    <note>a</note>
    <note>b</note>
  </measure>
</t>

We want to sort all "note" elements either (ascending) by their
contents or (descending) by their "print-spacing" attribute.

The following transformation does exactly this:

<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 
 <xsl:param name="vSrtCriterion" select="'contents'"/>
 <xsl:template match="/">
   <xsl:for-each select="/*/*/note">
     <xsl:sort 
      select="self::note[$vSrtCriterion = 'contents']"/>
      
     <xsl:sort 
     select="@print-spacing[not($vSrtCriterion = 'contents')]"
     order="descending"/>
     
     <xsl:copy-of select="."/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

The value of the "vSrtCriterion" parameter is ''contents''. The result
is sorted in ascending order by the contents of the "note" elements:

<note print-spacing="no">a</note>
<note print-spacing="no">a</note>
<note print-spacing="no">a</note>
<note>a</note>
<note print-spacing="no">b</note>
<note>b</note>
<note print-spacing="yes">b</note>
<note>b</note>

If we specify for the parameter "vSrtCriterion" some other value, then
the result is sorted in descending order by the value of the
"print-spacing" attributes:

<note print-spacing="yes">b</note>
<note print-spacing="no">a</note>
<note print-spacing="no">b</note>
<note print-spacing="no">a</note>
<note print-spacing="no">a</note>
<note>b</note>
<note>a</note>
<note>b</note>


This technique can be generalised to specify sorting by a set of many
mutually exclusive criteria.





=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread