Subject: RE: Sorting on a variable From: Kay Michael <Michael.Kay@xxxxxxx> Date: Mon, 16 Oct 2000 10:39:44 +0100 |
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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: SUMMARY: Re: Sorting on a varia, David Carlisle | Thread | grouping by child element, Keith |
RE: namespace-alias for remapping n, Kay Michael | Date | RE: JavaScript and XSL, Kay Michael |
Month |