[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

RE: Sorting on a variable

Subject: RE: Sorting on a variable
From: Kay Michael <Michael.Kay@xxxxxxx>
Date: Mon, 16 Oct 2000 10:39:44 +0100
javascript sort price currency
This is one of those things that "can't be done" in standard XSLT.

Two suggestions:
- create an (unsorted) copy of the node-set, adding the computed sort key as
an additional attribute, then use the node-set() extension to do a second
pass.
- use the saxon:function extension, which allows you to write an extension
function in XSLT and use it in contexts such as a sort key.
- try to write your computed sort key in pure XPath. Without conditional
expressions, it's not easy, but it can be done. There's a horrible hack that
relies on strange properties of the substring function:

substring("xyz", 1 div (condition)) equals "xyz" if condition is true, and
"" if condition is false.

Mike Kay

> -----Original Message-----
> From: John E. Simpson [mailto:simpson@xxxxxxxxxxx]
> Sent: 15 October 2000 18:06
> To: xsl-list@xxxxxxxxxxxxxxxx
> Subject: Sorting on a variable
> 
> 
> I've got XML which looks like this:
> 
> <products>
>    <product prodID="A1234">
>      <name>First prod</name>
>      <price curr="USD">29.95</price>
>    </product>
>    <product prodID="A5678">
>      <name>Second prod</name>
>      <price curr="GBP">29.95</price>
>    </product>
>    <product prodID="A9012">
>      <name>Third prod</name>
>      <price curr="EU">29.95</price>
>    </product>
>    <product prodID="A9012">
>      <name>Fourth prod</name>
>      <price curr="USD">50.00</price>
>    </product>
> </products>
> 
> No problem at all displaying this as a table, sorted (or not) 
> by name or 
> price. But then I wanted to sort not by raw price, but by a 
> single "USD 
> equivalent" -- converting the price to a common denomination.
> 
> Here's a variable to do the conversion (rates as of last night :):
> 
> <xsl:variable name="usd_equiv">
>    <xsl:choose>
>      <xsl:when test="price/@curr='USD'">
>        <xsl:value-of select="price"/>
>      </xsl:when>
>      <xsl:when test="price/@curr='GBP'">
>        <xsl:value-of select="price * 1.47275"/>
>      </xsl:when>
>      <xsl:when test="price/@curr='EU'">
>        <xsl:value-of select="price * 0.864379"/>
>      </xsl:when>
>      <xsl:otherwise>Unknown Currency</xsl:otherwise>
>    </xsl:choose>
> </xsl:variable>
> 
> (I've varied the values of the xsl:when test attributes in 
> different ways; 
> this is just the most current iteration, which assumes the 
> context node to 
> be a <product> element.)
> 
> Using a variable with xsl:sort introduces a number of 
> stylesheet structural 
> problems. E.g., if you do the sort within a for-each, the 
> xsl:sort must be 
> a first child of the xsl:for-each... and of course the 
> variable goes out of 
> scope for use *by* the xsl:sort. But if you do xsl:sort as a child of 
> xsl:apply-templates, well, xsl:variable is not a legitimate child of 
> xsl:apply-templates.
> 
> So then, rethinking a bit, I came up with what I thought was a fairly 
> simple solution, a global variable:
> 
> <xsl:variable name="product_usd">
>    <xsl:for-each select="/products/product">
>      <xsl:copy-of select="."/>
>      <usd_equiv>
>        <xsl:choose>
>          <xsl:when test="price/@curr='USD'">
>            <xsl:value-of select="price"/>
>          </xsl:when>
>          <xsl:when test="price/@curr='GBP'">
>            <xsl:value-of select="price * 1.47275"/>
>          </xsl:when>
>          <xsl:when test="price/@curr='EU'">
>            <xsl:value-of select="price * 0.864379"/>
>          </xsl:when>
>          <xsl:otherwise>Unknown Currency</xsl:otherwise>
>        </xsl:choose>
>      </usd_equiv>
>    </xsl:for-each>
> </xsl:variable>
> 
> Basically, this clones the <product> elements from the source 
> tree (with 
> xsl:copy-of select=".") into a variable ($prod_usd) as an 
> RTF. And -- I 
> thought -- it added an extra child element, <usd_equiv>, as a 
> child of each 
> <product> element. Then in the xsl:sort, instead of sorting 
> the source 
> tree, I'm sorting (with the node-set() function converting 
> this RTF to a 
> true node-set) the RTF contained by this variable, with 
> <usd_equiv> as my 
> sort key.
> 
> Near as I can tell, this should be giving me *something*. The 
> problem is 
> that the <usd_equiv> element always seems to be empty.
> 
> I feel really stupid. Must be missing something obvious... 
> and at this 
> point, have been banging my head against the problem for, 
> like, 6 hours.
> 
> Any ideas?
> 
> THANKS in advance!
> ===============================================================
> John E. Simpson               | "He asked me if I knew what
> http://www.flixml.org         | time it was. I said, 'Yes, but
> XML Q&A: http://www.xml.com   | not right now.'" (Steven Wright) 
> 
> 
>  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> 


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


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.