This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: IF-ELSE.. Sorting
- To: mail at jenitennison dot com
- Subject: [xsl] Re: IF-ELSE.. Sorting
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- Date: Mon, 18 Jun 2001 07:56:37 -0700 (PDT)
- Cc: xsl-list at lists dot mulberrytech dot com
- Reply-To: xsl-list at lists dot mulberrytech dot com
Jeni Tennison wrote:
[snip]
> However, as you want to use substring-before() and substring-after()
> in this case, you also need to do something complicated within the
> select attribute to alter what expression is used according to the
> $arrangeby parameter. Unfortunately, this isn't possible in pure XSLT
> 1.0, and you can't wrap the xsl:sort within a xsl:if or xsl:choose.
>
> It's easiest to this with two separate xsl:for-eaches:
>
> <xsl:choose>
> <xsl:when test="$arrangeby = 'DATE'">
> <xsl:for-each select="LIST/ASSIGN">
> <xsl:sort select="substring-before(DATE, 'T')"
> data-type="number" />
> ...
> </xsl:for-each>
> </xsl:when>
> <xsl:otherwise>
> <xsl:for-each select="LIST/ASSIGN">
> <xsl:sort select="*[name() = $arrangeby]" />
> ...
> </xsl:for-each>
> </xsl:otherwise>
> </xsl:choose>
>
> (You would probably be better off changing the xsl:for-eaches into
> xsl:apply-templates in this case - that way you could place the common
> processing in a common template rather than repeating it.)
>
> Or, if you're willing to use extensions and are using a processor like
> Saxon or Xalan that has an evaluate() function, then you could
> construct the expression that you want to use as a string within a
> variable, and then evaluate that expression within the select
> attribute. This also enables you to use an expression consisting of
> the value of the $arrangeby attribute (i.e. the name of the child
> element that you're using to sort by) rather than using *[name() =
> $arrangeby] to get at it:
>
> <xsl:variable name="selectExpression">
> <xsl:choose>
> <xsl:when test="$arrangeby = 'DATE'">
> <xsl:text>substring-before(DATE, 'T')</xsl:text>
> </xsl:when>
> <xsl:otherwise>
> <xsl:value-of select="$arrangeby" />
> </xsl:otherwise>
> </xsl:choose>
> </xsl:variable>
> <xsl:variable name="dataType">
> ...
> </xsl:variable>
> <xsl:for-each select="LIST/ASSIGN">
> <xsl:sort select="saxon:evaluate($selectExpression)"
> data-type="{$dataType}" />
> ...
> </xsl:for-each>
>
> (Note that to use this extension function you need to declare the
> 'saxon' namespace and be using Saxon; as I say, Xalan has a similar
> extension function if you're using that.)
This nice explanation illustrates extremely well why we need to use a generic sort
template in this case.
And, Jeni certainly knows that well, this kind of sorting can be achieved without
using any extension functions in 100% pure XSLT.
Where any use of a generic sort() will be natural, any attempt to use xsl:sort for
cases far from the most trivial -- these will look perverted and totally
incomprehensible to anybody but their author.
This is because xsl:sort needs a sort-key as ***one*** expression to be specified as
the value of its select attribute.
Contrary to this, a generic sort template leaves to the caller-supplied template the
definition of what a sort-key is and how sort-keys should be compared.
Cheers,
Dimitre Novatchev.
__________________________________________________
Do You Yahoo!?
Spot the hottest trends in music, movies, and more.
http://buzz.yahoo.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list