Re: [xsl] Sorting issue

Subject: Re: [xsl] Sorting issue
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Tue, 25 Jun 2002 10:50:05 +0100
Hi Andy,

> This is the xsl we tried to sort the xml with.
>
> <xsl:when test="$column = 'RateLockExp'">
> <xsl:apply-templates select="LoanSet/Loan">
> <xsl:sort select="LockCode"/>
> <xsl:sort select="substring( LockDate, 8, 4 )" data-type="number"/>
> <xsl:sort 
> select="format-number((string-length(substring-before('JanFebMarAprMayJunJulAugSepOctNovDec', 
> substring( LockDate, 4, 3 )) ) div 3 + 1), '00' )">
> <xsl:sort select="substring( LockDate, 1, 2 )" data-type="number"/>
> </xsl:apply-templates>
> </xsl:when>
>
> Using the XSL above, sorting works when testing with XT (all the
> rows with dates are displayed first, then the rows with words. The
> dates are sorted earliest to most recent. The words are sorted
> alphabetically), but not with Xalan (all the rows with dates are
> displayed first, then the rows with words. The dates, however, are
> displayed correctly in terms of month and day, but the years sort
> incorrectly, displaying in descending order, so that the most recent
> years are displayed first. The rows with words are sorted correctly,
> in alphabetical order) .

I'm surprised that this works. You first sort by LockCode, and then by
LockDate, which should mean that all the Loans are sorted
alphabetically before anything else, and only those Loans with the
same LockCode are sorted (relative to each other) by date.

When I try this code with the the example XML that you sent, I get:

Counter
12-May-2000
24-Jun-1999
Locked

in MSXML, Saxon and Xalan.

To do what you describe, you need to first sort by LockIndicator = 3,
so that those for which it is LockIndicator is 3 (the ones for which
you want to display dates) come before those for which LockIndicator
isn't 3:

  <xsl:sort select="LockIndicator = 3" />

You then need to sort those Loans whose LockIndicator is 3 by LockCode
(and *not* sort those Loans whose LockIndicator isn't 3 by LockCode);
you can do this by making sure that you only get a LockCode to sort by
for a particular Loan if its LockIndicator is 3:

  <xsl:sort select="LockCode[../LockIndicator = 3]" />

Finally, you need to sort by date. I guess it doesn't matter if, given
two Loans with the same LockCode, they're sorted by date as well, so
you can just use:

  <xsl:sort data-type="number"
    select="substring(LockDate, 8, 4)" />
  <xsl:sort data-type="number"
    select="string-length(
              substring-before('JanFebMarAprMayJunJulAugSepOctNovDec',
                               substring(LockDate, 4, 3)))" />
  <xsl:sort data-type="number"
    select="substring(LockDate, 1, 2)" />

With this sort specification, the result is:

24-Jun-1999
12-May-2000
Counter
Locked

as desired.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Current Thread