XSLT <xsl:sort> Element

Welcome to The Coding College, your go-to resource for coding tutorials! In this guide, we’ll delve into the <xsl:sort> element in XSLT. Sorting is a fundamental feature for transforming XML into well-organized output, and <xsl:sort> makes it effortless to sort nodes based on various criteria.

What Is the <xsl:sort> Element?

The <xsl:sort> element in XSLT is used to sort the nodes in a node set before processing them. It’s commonly used in conjunction with <xsl:for-each> or <xsl:apply-templates> to control the order of output.

Syntax

<xsl:sort select="XPath_expression" order="ascending|descending" data-type="text|number" />

Attributes:

  1. select (Required): Specifies the XPath expression to determine the sort key for each node.
  2. order (Optional): Sets the sort order:
    • ascending (default)
    • descending
  3. data-type (Optional): Determines the type of data being sorted:
    • text (default)
    • number
  4. case-order (Optional): For text sorting, specifies whether uppercase comes before or after lowercase:
    • upper-first
    • lower-first

How <xsl:sort> Works

  1. The <xsl:sort> element is placed inside <xsl:for-each> or <xsl:apply-templates>.
  2. The select attribute specifies the value to sort by, typically an element or attribute.
  3. The sorted node set is then processed in the specified order.

Example: Basic Sorting

Input XML:

<students>
  <student>
    <name>John</name>
    <score>85</score>
  </student>
  <student>
    <name>Jane</name>
    <score>92</score>
  </student>
  <student>
    <name>Smith</name>
    <score>78</score>
  </student>
</students>

XSLT Stylesheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <html>
      <body>
        <h1>Student Scores (Sorted)</h1>
        <ul>
          <xsl:for-each select="students/student">
            <xsl:sort select="score" order="descending" data-type="number" />
            <li>
              <xsl:value-of select="name" /> - <xsl:value-of select="score" />
            </li>
          </xsl:for-each>
        </ul>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Output HTML:

<html>
  <body>
    <h1>Student Scores (Sorted)</h1>
    <ul>
      <li>Jane - 92</li>
      <li>John - 85</li>
      <li>Smith - 78</li>
    </ul>
  </body>
</html>

Key Features of <xsl:sort>

1. Sorting by Text Values

Sort nodes alphabetically using data-type="text" (default).

Input XML:

<products>
  <product>
    <name>Laptop</name>
    <price>999.99</price>
  </product>
  <product>
    <name>Smartphone</name>
    <price>699.99</price>
  </product>
  <product>
    <name>Tablet</name>
    <price>399.99</price>
  </product>
</products>

XSLT Stylesheet:

<xsl:template match="/">
  <xsl:for-each select="products/product">
    <xsl:sort select="name" order="ascending" data-type="text" />
    <p><xsl:value-of select="name" /></p>
  </xsl:for-each>
</xsl:template>

Output:

Laptop
Smartphone
Tablet

2. Sorting Numerically

Use data-type="number" to sort numerical values properly.

Example: Sorting products by price in ascending order.

XSLT Snippet:

<xsl:for-each select="products/product">
  <xsl:sort select="price" data-type="number" />
  <p><xsl:value-of select="name" /> - $<xsl:value-of select="price" /></p>
</xsl:for-each>

Output:

Tablet - $399.99
Smartphone - $699.99
Laptop - $999.99

3. Case-Insensitive Sorting

By default, <xsl:sort> is case-sensitive. Use case-order="upper-first" or case-order="lower-first" to control case sorting.

Input XML:

<names>
  <name>zebra</name>
  <name>Apple</name>
  <name>banana</name>
</names>

XSLT:

<xsl:for-each select="names/name">
  <xsl:sort select="." case-order="lower-first" />
  <p><xsl:value-of select="." /></p>
</xsl:for-each>

Output:

Apple
banana
zebra

Sorting Multiple Keys

To sort by multiple criteria, include multiple <xsl:sort> elements. The processor uses the first <xsl:sort> as the primary key, the second as the secondary key, and so on.

Example: Sorting by Price (Ascending), then by Name (Alphabetically)

Input XML:

<products>
  <product>
    <name>Tablet</name>
    <price>399.99</price>
  </product>
  <product>
    <name>Smartphone</name>
    <price>699.99</price>
  </product>
  <product>
    <name>Laptop</name>
    <price>699.99</price>
  </product>
</products>

XSLT Stylesheet:

<xsl:for-each select="products/product">
  <xsl:sort select="price" data-type="number" />
  <xsl:sort select="name" data-type="text" />
  <p><xsl:value-of select="name" /> - $<xsl:value-of select="price" /></p>
</xsl:for-each>

Output:

Tablet - $399.99
Laptop - $699.99
Smartphone - $699.99

Best Practices

  1. Always Specify data-type: Avoid unexpected behavior by explicitly defining whether the data is text or number.
  2. Use Multiple <xsl:sort> Elements for Complex Sorting: Define a clear sorting hierarchy when sorting by multiple criteria.
  3. Combine with XPath: Use XPath expressions in the select attribute to dynamically select sort keys.

Limitations of <xsl:sort>

  1. Static Configuration: Sorting order and keys are defined statically in the XSLT stylesheet. For dynamic requirements, external tools or parameters may be needed.
  2. Node Ordering Only: Cannot reorder nodes outside of the <xsl:for-each> or <xsl:apply-templates> context.

Conclusion

The <xsl:sort> element is an essential tool for organizing and transforming XML data into clear and structured output. Whether you’re building a sorted list, managing multiple criteria, or controlling the order of processing, <xsl:sort> gives you precise control.

Leave a Comment