Sorting and Merging

For simplicity, the examples in this section use sequences of integers and strings; XPath expressions and nodes can be used in the same way. For instance, an XML-based merge source can be written as:
<xsl:merge-source for-each="doc(a.xml), doc(b.xml)" select="a/b/@c">…

This selects the a/b/@c attribute from each document named in the for-each list as a separate merge source.

<xsl:perform-sort>, <xsl:sort>

<xsl:perform-sort> sorts a sequence using one or more <xsl:sort> keys, applied in order.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:fn="http://www.w3.org/2005/xpath-functions">
  <xsl:template match="/">
     <xsl:perform-sort select="('1a','3b','8b','4b','2','1c','1b')">
        <xsl:sort select="substring(.,1,1)"/>
        <xsl:sort select="substring(.,2,1)"
                      order="descending"/>
     </xsl:perform-sort>
   </xsl:template>
</xsl:transform>

1c 1b 1a 2 3b 4b 8b
<xsl:sort> can have the following attributes: select (expression), lang ({language}), order ({"ascending" | "descending"}), collation ({uri}), stable ({"yes" | "no"}), case-order ({"upper-first" | "lower-first"}), data-type ({"text" | "number" | eqname}).

<xsl:merge>, <xsl:merge-source>, <xsl:merge-key>, <xsl:merge-action>

<xsl:merge> merges several already-sorted (or sort-on-the-fly) sources into a single sequence, grouping items that share the same merge key. The example below merges three numeric sources on different keys.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:fn="http://www.w3.org/2005/xpath-functions">
   <xsl:template match="/" name="xsl:initial-template">
     <xsl:merge>
       <xsl:merge-source for-each-item="(1,100)"
                 select="(.*5,.*3,.*1,.*7,.*9)" sort-before-merge="yes">
          <xsl:merge-key select="."/>
       </xsl:merge-source>
       <xsl:merge-source
                 select="(4,10,2,8,6)" sort-before-merge="yes">
          <xsl:merge-key select=". * 10"/>
       </xsl:merge-source>
       <xsl:merge-source select="(5)">
          <xsl:merge-key select=". * 10"/>
       </xsl:merge-source>
       <xsl:merge-action>
         <xsl:value-of select="current-merge-group()"/>
         <xsl:text>&#32;</xsl:text>
         <xsl:value-of select="current-merge-key()"/>
         <xsl:text>&#10;</xsl:text>
       </xsl:merge-action>
     </xsl:merge>
   </xsl:template>
</xsl:transform>

2 20 4 40 5 50 6 60 8 80 100 100 10 100 300 300 300 500 500 500 700 700 700 900 900 900
<xsl:merge-source> can have the following attributes: bind-source (eqname), streamable ("yes" | "no"), sort-before-merge ("yes" | "no").
<xsl:merge-key> can have the following attributes: lang ({language}), order ({"ascending" | "descending"}), collation ({uri}), case-order ({"upper-first" | "lower-first"}), data-type ({"text" | "number" | eqname}).