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