Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office - XSLT Developer's Guide

Step 3: Sorting the Source Tree Clone

To sort the modified clone of the source tree, convert it to a node-set, using the msxsl:node-set() function. Then pass it, in its sorted form, to a template rule that handles it the same way the original source tree itself would be handled.

To do this, add some new lines to the template rule for the root <products> element. This is illustrated in the example below.

Note   To use the msxsl:node-set() function, the style sheet's <xml:stylesheet> element must include the following namespace declaration:
xmlns:msxsl="urn:schemas-microsoft-com:xslt"

Example

In the formatted output at the end of this topic, note the position of the Virtual Widgets product. If the products had been sorted by the <price> element alone, the position of this product would be considerably different.

Also note the new column in the table, which lists the value of the new <usd_equiv> element.

For this technique to work, the style sheet must not include a namespace declaration for the HTML 4.0 namespace, which you will typically include when transforming XML to HTML that is compatible with Internet Explorer. This is because the generated <usd_equiv> element, which includes no namespace prefix, is in the default namespace. But because <usd_equiv> is not an HTML element, it will not appear in the result tree.

XML File (prodsort.xml)

Use prodsort.xml, in Sample XML Data File for XSLT Sorting. Change the href attribute to reference prodsortcvar.xsl.

XSLT File (prodsortcvar.xsl)

The product template rule with a mode attribute and a new <xsl:apply-templates> element invokes another product template rule. This rule is used for <product> elements that do not have a mode attribute. These two template rules are shown below, and the prodsortcvar.xsl file is now complete. For the entire completed prodsortcvar.xsl file, see Sample XSLT File for Sorting.

<xsl:template match="products">
    <!-- Create a variable to hold the generated result tree fragment. -->
    <xsl:variable name="prods_with_usd">
        <xsl:apply-templates select="product" mode="calc_usd" />
    </xsl:variable>
    <TABLE width="75%">
        <tr>
            <th>Category</th>
            <th>Prod ID</th>
            <th>Name/Version</th>
            <th>Description</th>
            <th>Price (Currency)</th>
            <th>Price (USD)</th>
        </tr>
        <!-- Fill remainder of table with source tree "clone". -->
        <xsl:apply-templates select="msxsl:node-set($prods_with_usd)/product">
            <xsl:sort select="usd_equiv" data-type="number" />
        </xsl:apply-templates>
    </TABLE>
</xsl:template>

<xsl:template match="product">
    <tr>
        <td valign="top"><xsl:value-of select="categ"/></td>
        <td valign="top"><xsl:value-of select="@prodID"/></td>
        <td valign="top"><xsl:value-of select="concat(name, '/', version)"/></td>
        <td valign="top"><xsl:value-of select="descr"/></td>
        <td valign="top" align="center"><xsl:value-of select="concat(price, ' (', price/@curr, ')')"/></td>
        <td valign="top" align="right"><xsl:value-of select="usd_equiv"/></td>
    </tr>
</xsl:template>

</xsl:stylesheet>

Formatted Output

Processor Output

A portion of the output is shown here.

<HTML xmlns:msxsl="urn:schemas-microsoft-com:xslt">
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-16">
<TITLE>Wooden Rings and More!</TITLE>
<STYLE type="text/css">
            th {background-color: silver;
               font-family: Tahoma,Verdana,Arial,sans-serif}
            td {background-color: white;
               font-family: Tahoma,Verdana,Arial,sans-serif}
         </STYLE>
</HEAD>
<BODY>
<TABLE width="75%">
<tr>
<th>Category</th>
<th>Prod ID</th>
<th>Name/Version</th>
<th>Description</th>
<th>Price (Currency)</th>
<th>Price (USD)</th>
</tr>
<tr>
<td valign="top">Craftware</td>
<td valign="top">WR1016</td>
<td valign="top">Wooden Rings/1.6</td>
<td valign="top">Our best-selling oaken toroids</td>
<td valign="top" align="center">27.99 (USD)</td>
<td valign="top" align="right">27.99</td>
</tr>
<tr>
<td valign="top">Software</td>
...
</TABLE>
</BODY>
</HTML>