Subject: RE: [xsl] sorting a subset of elements From: Jarno.Elovirta@xxxxxxxxx Date: Thu, 22 Aug 2002 09:30:01 +0300 |
Hi, > I have created an xml document with over 300 items sorted by > price. For the > internet I want to display all items, however for print I only want to > display the 90 most expensive and i want them sorted > alpabetically. I am > not sure how to accomplish this. You can't sort, filter and sort again with XSLT 1.0; using XSLT 1.1 or 2.0 you could sort the items into a variable and sort it again. So, either do two transformations, where you sort by price and filter in the first one, and sort by name in the second one; or write a recursive template that will select the first 50 most expensive items, but that will probably be quite inefficient, e.g. (should work) <?xml version='1.0' encoding='UTF-8' ?> <xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> <xsl:template match="itemlist"> <xsl:copy> <xsl:call-template name="max-n"> <xsl:with-param name="ns" select="item" /> </xsl:call-template> </xsl:copy> </xsl:template> <xsl:template match="item"> <xsl:copy-of select="." /> </xsl:template> <xsl:template name="max-n"> <xsl:param name="ns" select="/.." /> <xsl:param name="selected" select="/.." /> <xsl:param name="n" select="50"/> <xsl:choose> <xsl:when test="not(count($ns) = 0) and count($selected) < $n"> <xsl:variable name="max"> <xsl:call-template name="max"> <xsl:with-param name="ns" select="$ns" /> </xsl:call-template> </xsl:variable> <xsl:variable name="tbs" select="$ns[@price = $max]" /> <xsl:call-template name="max-n"> <xsl:with-param name="ns" select="$ns[not(@price = $max)]" /> <xsl:with-param name="selected" select="$selected | $ns[@price = $max][position() < ($n + 1 - count($selected))]" /> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="$selected"> <xsl:sort select="@description" /> </xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="max"> <xsl:param name="ns" select="/.." /> <xsl:choose> <xsl:when test="count($ns) > 2"> <xsl:variable name="c" select="ceiling(count($ns) div 2)" /> <xsl:variable name="head"> <xsl:call-template name="max"> <xsl:with-param name="ns" select="$ns[position() <= $c]" /> </xsl:call-template> </xsl:variable> <xsl:variable name="tail"> <xsl:call-template name="max"> <xsl:with-param name="ns" select="$ns[position() > $c]" /> </xsl:call-template> </xsl:variable> <xsl:choose> <xsl:when test="$head > $tail"> <xsl:value-of select="$head" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$tail" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:when test="count($ns) > 1"> <xsl:choose> <xsl:when test="$ns[1]/@price > $ns[2]/@price"> <xsl:value-of select="$ns[1]/@price" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="$ns[2]/@price" /> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:value-of select="$ns/@price" /> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet> But you do not want that with 300 items, especially if just about every item has a unique price; so go with the two (chained) transformations. Cheers, Jarno XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Multiple Sorts problem, Jitu | Thread | RE: [xsl] sorting a subset of eleme, Dion Houston |
[xsl] debugging XSLT, Bernd Gauweiler | Date | RE: [xsl] SVG, no actual output, Jarkko . Moilanen |
Month |