XSLT - Using <xsl:perform-sort> for Programmatic Sorting

The <xsl:perform-sort> instruction in XSLT is used when sorting needs to be performed explicitly and programmatically within a transformation. Unlike the commonly used <xsl:sort> instruction, which is normally placed inside <xsl:for-each> or <xsl:apply-templates>, <xsl:perform-sort> allows a sequence of items to be sorted as an independent operation. This makes it useful when the sorted result needs to be stored, processed, or passed to another part of an XSLT transformation.

The basic structure of <xsl:perform-sort> is:

<xsl:perform-sort select="expression">
    <xsl:sort select="sorting-expression"/>
</xsl:perform-sort>

The select attribute identifies the sequence that should be sorted. The <xsl:sort> child element specifies how the items should be ordered. The sorting expression can select an element, attribute, calculated value, or other expression from each item in the sequence.

For example, consider the following XML document:

<students>
    <student>
        <name>Ravi</name>
        <marks>75</marks>
    </student>
    <student>
        <name>Anita</name>
        <marks>92</marks>
    </student>
    <student>
        <name>John</name>
        <marks>81</marks>
    </student>
</students>

A transformation can sort the students according to their marks using <xsl:perform-sort>:

<xsl:variable name="sorted-students">
    <xsl:perform-sort select="/students/student">
        <xsl:sort select="marks" data-type="number" order="descending"/>
    </xsl:perform-sort>
</xsl:variable>

Here, /students/student selects all the student elements. The <xsl:sort> instruction sorts them according to the value of marks. The data-type="number" option ensures that the marks are treated as numerical values rather than strings, while order="descending" places the highest marks first. The resulting sorted sequence is stored in the $sorted-students variable.

One important advantage of <xsl:perform-sort> is that it separates sorting from processing. With a traditional <xsl:sort>, sorting is directly associated with an iteration or template application. With <xsl:perform-sort>, the transformation can first create a sorted sequence and then use that sequence for another operation. This can make complex transformations easier to organize, particularly in XSLT 2.0 and later versions where sequences are an important part of the language.

Multiple sorting criteria can also be specified. For example, suppose students should first be sorted by marks in descending order and then by name alphabetically when two students have the same marks:

<xsl:perform-sort select="/students/student">
    <xsl:sort select="marks" data-type="number" order="descending"/>
    <xsl:sort select="name" order="ascending"/>
</xsl:perform-sort>

The first <xsl:sort> is the primary sorting condition. The second is used when two or more items have the same value for the first condition. This allows <xsl:perform-sort> to handle hierarchical or multi-level sorting requirements.

It is also possible to sort based on calculated expressions rather than directly on an XML element. For example:

<xsl:perform-sort select="/products/product">
    <xsl:sort select="price * quantity" data-type="number" order="descending"/>
</xsl:perform-sort>

In this example, the sorting value is calculated by multiplying price by quantity. Products are therefore ordered according to their calculated total value. This demonstrates how sorting can be combined with XPath expressions to handle more advanced requirements.

The <xsl:perform-sort> instruction is particularly useful when a transformation needs to manipulate sequences independently of the output process. It can be used with variables, functions, conditional processing, and other XSLT constructs. However, it is important to remember that the instruction is primarily associated with XSLT 2.0 and later, so it should not be used in transformations that must remain compatible with XSLT 1.0 processors.

In summary, <xsl:perform-sort> provides a way to explicitly sort a sequence within an XSLT transformation. It supports single and multiple sorting criteria, ascending and descending order, numeric and textual sorting, and sorting based on calculated expressions. Its main benefit is that it treats sorting as a distinct operation, making it suitable for transformations where the sorted sequence needs to be independently stored or further processed.