
Sorting in XSLT
by Bob DuCharme
July 03, 2002
XSLT's xsl:sort instruction lets you sort a group of
similar elements. Attributes for this element let you add details
about how you want the sort done -- for example, you can sort using
alphabetic or numeric ordering, sort on multiple keys, and reverse the
sort order.
Related Reading
XSLT
By DougTidwell
Table of Contents
Index
Sample Chapter
Author's Article
Read Online--Safari
To demonstrate different ways to sort, we'll use the following
document.
<employees>
<employee hireDate="04/23/1999">
<last>Hill</last>
<first>Phil</first>
<salary>100000</salary>
</employee>
<employee hireDate="09/01/1998">
<last>Herbert</last>
<first>Johnny</first>
<salary>95000</salary>
</employee>
<employee hireDate="08/20/2000">
<last>Hill</last>
<first>Graham</first>
<salary>89000</salary>
</employee>
</employees>
(All stylesheets, input documents, and output documents shown in
this article are in this zip file.) This
first stylesheet sorts the employee children of the
employees element by salary.
<!-- xq424.xsl: converts xq423.xml into xq425.xml -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="employees">
<xsl:apply-templates>
<xsl:sort select="salary"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="employee">
Last: <xsl:apply-templates select="last"/>
First: <xsl:apply-templates select="first"/>
Salary: <xsl:apply-templates select="salary"/>
Hire Date: <xsl:apply-templates select="@hireDate"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
It's pretty simple. The employees element's template has
an xsl:apply-templates instruction with an xsl:sort
child to tell the XSLT processor to sort the employees
element's child elements. The xsl:sort instruction's
select attribute specifies the sort key to use: the
employee elements' salary values. (If you omit the
select attribute, the XSLT processor uses a string version of
the elements to be sorted as a sort key.) The employee
element's template rule adds each of its child node's values to the
result tree preceded by a label, and a final xsl:text element
adds a carriage return after each hire date value.
Note Most
xsl:apply-templates elements you see in XSLT stylesheets are
empty. When you sort an element's children, the xsl:sort
element goes between the start- and end-tags of the
xsl:apply-templates element that tells the XSLT processor to
process these children. The only other place you can put an
xsl:sort instruction is inside of the xsl:for-each
instruction used to iterate across a node set, as we'll see
below.
With the document above, this stylesheet gives us this
output:
Last: Hill
First: Phil
Salary: 100000
Hire Date: 04/23/1999
Last: Hill
First: Graham
Salary: 89000
Hire Date: 08/20/2000
Last: Herbert
First: Johnny
Salary: 95000
Hire Date: 09/01/1998
The employees are sorted by salary, but they're sorted
alphabetically -- "1" comes before "8" and "9", so a salary of
"100000" comes first. But we want the salary values treated
as numbers, so we make a simple addition to the template's
xsl:sort instruction:
<!-- xq426.xsl: converts xq423.xml into xq427.xml -->
<xsl:template match="employees">
<xsl:apply-templates>
<xsl:sort select="salary" data-type="number"/>
</xsl:apply-templates>
</xsl:template>
Now, the output is sorted by the salary
element's numeric value:
Last: Hill
First: Graham
Salary: 89000
Hire Date: 08/20/2000
Last: Herbert
First: Johnny
Salary: 95000
Hire Date: 09/01/1998
Last: Hill
First: Phil
Salary: 100000
Hire Date: 04/23/1999
[1] [2] [3] [4] Next