XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

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.)



1 to 10 of 10
  1. great article thanks
    2009-05-09 09:14:10 jixel
  2. xsl:sort
    2007-07-13 06:16:06 ArsenyX
  3. sort
    2005-11-28 12:51:49 harvy
    • sort
      2006-04-20 05:58:37 jbautista
  4. Custom built xsl:sort
    2005-09-06 18:49:53 srinivasvemuri
  5. Xml and XSLT
    2004-04-27 00:52:07 bertcox
  6. static or dynamic...?
    2004-01-10 13:10:05 john clariond
  7. Parameters
    2002-09-04 03:53:25 Dave Goodman
  8. xsl:sort
    2002-08-02 00:49:54 aneesh kumar
    • xsl:sort
      2002-08-13 06:03:14 charles asafo
  9. xsl:sort
    2002-07-04 09:07:34 Vijayalaxmi Balcha
  10. Use of xsl:sort
    2002-07-04 05:38:50 Raj Krishnan
1 to 10 of 10