[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] 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
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|