15.4 Using EXSLT

You'll get to use several EXSLT extensions in the following example. Here is a simple order for oats from a feed store represented in XML (order.xml), shown in Example 15-5.

Example 15-5. An order for oats, in XML
<?xml version="1.0"?>     <order >  <store>Prineville</store>  <product>feed-grade whole oats</product>  <package>sack</package>  <weight std="lbs.">50</weight>  <quantity>23</quantity>  <price cur="USD">   <high>5.99</high>   <regular>4.99</regular>   <discount>3.99</discount>  </price>  <ship>the back of Tom's pickup</ship> </order>

The EXSLT extensions in Example 15-6, the stylesheet order.xsl, augment the order with date and time.

Example 15-6. A stylesheet that does mathematical computations using the EXSLT math functions
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:date="http://exslt.org/dates-and-times" xmlns:math="http://exslt.org/math"> <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/> <xsl:strip-space elements="*"/>     <xsl:template match="order">  <xsl:copy>   <xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>   <date><xsl:value-of select="date:date(  )"/></date>   <time><xsl:value-of select="date:time(  )"/></time>   <xsl:copy-of select="product|package|weight|quantity"/>   <price cur="{price/@cur}"><xsl:value-of select="math:lowest(price/*)"/></price>   <total><xsl:value-of select="format-number(math:lowest(price/*)*quantity,'#,###.00')"/></total>   <xsl:copy-of select="ship"/>  </xsl:copy> </xsl:template>     </xsl:stylesheet>

Using the date:date( ) and date:time( ) functions from the dates and times module, and the math:lowest( ) function from the math module, order.xsl transforms and improves upon the information in the original order.xml. The date:date( ) and date:time( ) functions provide the system date and time to the result tree respectively. The math:lowest( ) function takes a node-set as an argument. The function then selects the node having the lowest value, in this case 3.99.

Instant Saxon supports these EXSLT functions, so you can get results by issuing the following command:

saxon order.xml order.xsl

This will produce the following results:

<?xml version="1.0" encoding="ISO-8859-1"?> <order >    <date>2003-05-09</date>    <time>09:00:39-07:00</time>    <product>feed-grade whole oats</product>    <package>sack</package>    <weight std="lbs.">50</weight>    <quantity>23</quantity>    <price cur="USD">3.99</price>    <total>91.77</total>    <ship>the back of Tom's pickup</ship> </order>

15.4.1 EXSLT's exsl:node-set Function

Like Saxon, EXSLT also has a function for converting result tree fragments into node-sets. It's called exsl:node-set( ). The enode-set.xsl stylesheet shown in Example 15-7 is very similar to node-set.xsl.

Example 15-7. A stylesheet using the EXSLT node-set( ) function
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"> <xsl:output method="xml" indent="yes"/> <xsl:variable name="frag"> <python>  <description>Python 2.3 String Escapes</description>  <escape purpose="ignore EOL">\</escape>  <escape purpose="backslash">\\</escape>  <escape purpose="octal value">\ddd</escape>  <escape purpose="hexadecimal">\xXX</escape>  <escape purpose="other">\other</escape>  <escape purpose="single quote">\'</escape>  <escape purpose="double quote">\"</escape> </python> </xsl:variable>     <xsl:template match="python">  <xsl:copy>   <xsl:copy-of select="exsl:node-set($frag)/python/*"/>   <xsl:apply-templates select="escape"/>  </xsl:copy> </xsl:template>     <xsl:template match="escape">  <xsl:copy-of select="."/> </xsl:template>     </xsl:stylesheet>

The only differences are the namespace and prefix. If you apply this against escapes.xml with Saxon, you will get the same result you got when using node-set.xsl. Saxon supports many but not all EXSLT extensions; however, Saxon's documentation states that it prefers that users work with EXSLT's extensions over Saxon's (see http://saxon.sourceforge.net/saxon6.5.2/extensions.html or http://saxon.sourceforge.net/saxon7.5/extensions.html).

Many EXSLT extensions are also implemented as pure XSLT 1.0, meaning that they use imported templates in tandem with call-template to implement the functionality (nevertheless, some extensions like node-set( ) cannot be implemented in XSLT 1.0 alone). The call-template element acts as a function call. These pure implementations, however, are several years old, and I could not get a number of them to work as advertised, try as I may. Therefore, I won't be exploring them here.



Learning XSLT
Learning XSLT
ISBN: 0596003277
EAN: 2147483647
Year: 2003
Pages: 164

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net