Sorting in XSLT
by Bob DuCharme
|
Pages: 1, 2, 3, 4
Let's look at how the xsl:for-each instruction can use xsl:sort. The following stylesheet takes the same winelist document above and lists the wines. When it gets to a Chardonnay, it lists all the other Chardonnays alphabetically.
<!-- xq439.xsl: converts xq436.xml into xq440.txt -->
<!DOCTYPE stylesheet [
<!ENTITY space "<xsl:text> </xsl:text>">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="wine">
<xsl:apply-templates select="winery"/>&space;
<xsl:apply-templates select="product"/>&space;
<xsl:apply-templates select="year"/>&space;
<xsl:apply-templates select="@grape"/>
<xsl:if test="@grape = 'Chardonnay'">
<xsl:text>
other Chardonnays:
</xsl:text>
<xsl:for-each
select="preceding-sibling::wine[@grape = 'Chardonnay'] |
following-sibling::wine[@grape = 'Chardonnay']">
<xsl:sort select="winery"/>
<xsl:text> </xsl:text>
<xsl:value-of select="winery"/>&space;
<xsl:value-of select="product"/><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:if>
</xsl:template>
Before we examine how the stylesheet does this, let's take a look at the result:
Lindeman's Bin 65 1998 Chardonnay
other Chardonnays:
Benziger Carneros
Kendall Jackson Vintner's Reserve
Benziger Carneros 1997 Chardonnay
other Chardonnays:
Kendall Jackson Vintner's Reserve
Lindeman's Bin 65
Duckpond Merit Selection 1996 Cabernet
Kendall Jackson Vintner's Reserve 1998 Chardonnay
other Chardonnays:
Benziger Carneros
Lindeman's Bin 65
(First, notice the "&space;" entity references throughout the stylesheet. Instead of writing "<xsl:text> </xsl:text>" over and over because I needed single spaces in so many places, it was easier to declare an entity named space in the DOCTYPE declaration with this xsl:text element as content and to then plug it in with an entity reference whenever I needed it.) The xsl:template template rule for the wine element has xsl:apply-templates instructions for its winery, product, and year element children followed by one for its grape attribute. Then, if the grape attribute has a value of "Chardonnay", it adds the text "other Chardonnays:" to the result tree followed by the list of Chardonnays, which are added to the result tree using an xsl:for-each instruction.
The select attribute of the xsl:for-each attribute selects all the nodes that are either preceding siblings of the current node with a grape value of "Chardonnay" or following siblings of the current node with the same grape value. (The "|" symbol is the "or" part.) For each wine element that meets this select attribute's condition, the template first adds some white space indenting with an xsl:text element, then the value of the wine element's winery child, a space, and the value of its product child. The first instruction in this xsl:for-each element is an xsl:sort element, which tells the XSLT processor to sort the nodes selected by the xsl:for-each instruction alphabetically in "winery" order. That's how they look in the result: after the first "other Chardonnays:" label, "Kendall Jackson" comes after "Benziger"; after the second, "Lindeman's" comes after "Kendall Jackson"; and after the last one, "Lindeman's" comes after "Benziger".
Because the xsl:for-each instruction lets you grab and work with any node set that you can describe using an XPath expression, the ability to sort one of these node sets makes it one of XSLT's most powerful features.
Next month, we'll see how xsl:sort can help find the first, last, biggest, and smallest value in a document according to a certain criteria. (If you can't wait, see my book XSLT Quickly, from which these columns are excerpted.)
- great article thanks
2009-05-09 09:14:10 jixel - xsl:sort
2007-07-13 06:16:06 ArsenyX - sort
2005-11-28 12:51:49 harvy - sort
2006-04-20 05:58:37 jbautista - Custom built xsl:sort
2005-09-06 18:49:53 srinivasvemuri - Custom built xsl:sort
2005-09-06 19:23:45 Bob DuCharme - Custom built xsl:sort
2005-09-07 12:22:45 srinivasvemuri - Custom built xsl:sort
2005-09-07 14:02:01 Bob DuCharme - Xml and XSLT
2004-04-27 00:52:07 bertcox - Xml and XSLT
2004-05-29 06:56:13 Kitsuneymg - static or dynamic...?
2004-01-10 13:10:05 john clariond - static or dynamic...?
2004-05-29 06:58:01 Kitsuneymg - Parameters
2002-09-04 03:53:25 Dave Goodman - Parameters
2004-05-29 07:00:03 Kitsuneymg - Parameters
2004-04-20 04:43:04 SK - Parameters
2004-04-20 04:37:28 SK - Parameters
2004-04-20 04:34:39 SK - xsl:sort
2002-08-02 00:49:54 aneesh kumar - xsl:sort
2002-07-04 09:07:34 Vijayalaxmi Balcha - Use of xsl:sort
2002-07-04 05:38:50 Raj Krishnan