Subject: RE: multiple sorting From: "Caras, Yuko" <Yuko_Caras@xxxxxxxxxxxxxxxxx> Date: Tue, 15 Aug 2000 15:20:56 -0700 |
Jeni, They work beautifully! Thank you :-) Yuko -----Original Message----- From: Jeni Tennison [mailto:mail@xxxxxxxxxxxxxxxx] Sent: Tuesday, August 15, 2000 1:31 PM To: Caras, Yuko Cc: 'XSL-List@xxxxxxxxxxxxxxxx' Subject: Re: multiple sorting Yuko, I can see what you're trying to do here. Basically, if the name of the element to be sorted on is 'name' or 'lead', then you want to sort alphabetically in ascending order, whereas if it's 'score' or 'time', then you want to sort numerically in descending order. The trouble is that you can't conditionally add sorts within a xsl:for-each (or xsl:apply-templates). There are two ways that I can see of going about it: METHOD 1 -------- You could have two versions of the xsl:for-each that iterates over the rows: one that sorted alphabetically in ascending order, and another that sorted them numerically in descending order, with the $item determining which of the xsl:for-eaches was used. In this case, it's probably best to separate off your row-matching template and use xsl:apply-templates rather than xsl:for-each, to prevent having to repeat yourself unnecessarily: <xsl:choose> <xsl:when test="$item = 'name' or $item = 'lead'"> <xsl:apply-templates select="row"> <xsl:sort select="*[name() = $item]" data-type="text" order="ascending" /> </xsl:apply-templates> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="row"> <xsl:sort select="*[name() = $item]" data-type="number" order="descending" /> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> ... <xsl:template match="row"> <tr> <xsl:for-each select="name"> <td><xsl:value-of select="."/></td> </xsl:for-each> <xsl:for-each select="score"> <td><xsl:value-of select="."/></td> </xsl:for-each> <xsl:for-each select="time"> <td><xsl:value-of select="."/></td> </xsl:for-each> <xsl:for-each select="lead"> <td><xsl:value-of select="."/></td> </xsl:for-each> </tr> </xsl:template> [Actually, this should probably be: <xsl:template match="row"> <tr> <td><xsl:value-of select="name"/></td> <td><xsl:value-of select="score"/></td> <td><xsl:value-of select="time"/></td> <td><xsl:value-of select="lead"/></td> </tr> </xsl:template> as long as there's only one name, score, time and lead per row.] METHOD 2 -------- You could do something clever with the sort so that a particular xsl:sort instruction would only actually made a difference if a certain case was true. For example, if you did: <xsl:for-each select="row"> <xsl:sort select="(name | lead)[name() = $item]" data-type="text" order="ascending" /> <xsl:sort select="(score | time)[name() = $item]" data-type="number" order="descending" /> <tr> <td><xsl:value-of select="name"/></td> <td><xsl:value-of select="score"/></td> <td><xsl:value-of select="time"/></td> <td><xsl:value-of select="lead"/></td> </tr> </xsl:for-each> then the select would only be able to find a node to use to sort with for the first xsl:sort if $item was either 'name' or 'lead'. Without such a value, it would have nothing to sort on, and the instruction would have no effect. Similarly, the second xsl:sort would only get a sort value if $item were either 'score' or 'time'. I think this is a pretty neat way of doing it :) I've tested it and it works in SAXON. I hope that helps, Jeni Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: multiple sorting, Caras, Yuko | Thread | RE: multiple sorting, Caras, Yuko |
RE: [ANN] Change Stylesheet Power T, Chris Bayes | Date | RE: dtd, sara . mitchell |
Month |