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 themsxsl:node-set()
function, the style sheet's<xml:stylesheet>
element must include the following namespace declaration:
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
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>