<xsl:sort>

XSLT Function: <xsl:sort>The XSLT <xsl:sort> element is used to apply an ordering on the results selected by a <xsl:for-each> element.

Sorted values are often required when presenting data; or for some other purpose. The <xsl:sort> element allows you to sort XML data and output as required. The use of the element has a number of rules:

  • <xsl:sort> can be used inside an <xsl:for-each> element.
  • <xsl:sort> must be the first instruction – before any others – inside the <xsl:for-each> element.


Syntax

All attributes are optional and can be omitted if the default behavior is sufficient for your ordering requirements. The default implementation sorts the current node is sorted alphabetically in an ascending order.

<xsl:sort />

To override the default behavior, define any of the attributes as follows:

<xsl:sort select="expression" data-type="text|number|qname" order="ascending|descending" case-order="upper-first|lower-first" />


where expression is an XPATH expression referencing a key accessible from the current node. The XPATH expression is a relative path. Refer to the attributes section for acceptable values.

Attributes

NameMandatory / OptionalDescription
selectOPTIONALDefines the key to sort on using an XPATH expression. If no key is selected then the node-value is used.
data-typeOPTIONALnumber or text
Define number as the data type to get more accurate results when sorting numbers.
orderOPTIONALTo sort values ascending set the attribute to ASCENDING,
To sort values in descending order set the attribute to DESCENDING.
case-orderOPTIONALDefines which case receives precedence when sorting strings.
lower-first sets lower case characters first.
upper-first set the upper case characters first.

Examples

For our examples we are using the fictional library as an input XML. Any XSL transform examples we define uses this XML as an input:

<?xml version="1.0" encoding="UTF-8"?>
<library>
<category name="dogs">
<book>
<name>All about dogs</name>
<author>Someone</author>
<isin>true</isin>
<daysuntilreturn>0</daysuntilreturn>
</book>
<book>
<name>Spots on dogs</name>
<author>Someone</author>
<isin>false</isin>
<daysuntilreturn>02</daysuntilreturn>
</book>
<book>
<name>Bark like me</name>
<author>Someone</author>
<isin>false</isin>
<daysuntilreturn>05</daysuntilreturn>
</book>
</category>
<category name="cats">
<book>
<name>All about cats</name>
<author>Someone</author>
<isin>false</isin>
<daysuntilreturn>3</daysuntilreturn>
</book>
<book>
<name>Meoww</name>
<author>Someone</author>
<isin>false</isin>
<daysuntilreturn>03</daysuntilreturn>
</book>
</category>
</library>

 

How to sort alphabetical values

The following XSL transform selects all the books in our library and orders them alphabetically by name in an ascending order.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="/library/category/book">
<xsl:sort select="./name" order="ASCENDING" />
Book: <xsl:value-of select="./name"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

The results of the above XSL transform orders the book names as follows:

   1: All about cats

   2: All about dogs

   3: Bark like me

   4: Meoww

   5: Spots on dogs

How to sort numeric values

Numeric sorting is used in cases where alphabetic sorting returns an invalid ordering. Alphabetic sorting orders values based on character value – not numeric value. If sorting alphabetically on the daysuntilreturn node value then the result will be:

   1: 0

   2: 02

   3: 03

   4: 05

   5: 3

The above values are ordered alphabetically; however, the ordering is invalid when considering the actual values represented by the daysuntilreturn node – Note lines 4 and  5 – the number 3 should precede the number 5 (05).

Numeric sorting provides a more accurate result.

The following XSL transform selects all the books in our library and orders them numerically by daysuntilreturn in an ascending order.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="/library/category/book">
<xsl:sort select="./daysuntilreturn" data-type="number" order="ASCENDING" />
Days Until Return: <xsl:value-of select="./daysuntilreturn"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

The results of the above transform has a different ordering; note the difference on lines 4 and 5.

   1: 0

   2: 02

   3: 03

   4: 3

   5: 05

Posted in XSLT and tagged .

Leave a Reply