15.3 Result Tree Fragment to Node-Set

As you learned in Chapter 7, a variable can hold a special XSLT type called a result tree fragment. Such a fragment can hold XML nodes, but it isn't natively treated as a node-set. Nonetheless, with Xalan's node-set( ) function or Saxon's nodeset( ), you can cast a result tree fragment as a node-set and manipulate it as such. The following example will apply node-set( ) from Xalan (note, however, that many processors now provide the EXSLT version of this function for portability).

Consider the document escapes.xml, which lists most of the string escapes offered by Python Version 2.3:

<?xml version="1.0"?>     <python version="2.3">  <escape purpose="bell">\a</escape>  <escape purpose="backspace">\b</escape>  <escape purpose="formfeed">\f</escape>  <escape purpose="newline">\n</escape>  <escape purpose="carriage return">\r</escape>  <escape purpose="horizontal tab">\t</escape>  <escape purpose="vertical tab">\v</escape> </python>

There are a few escapes missing from this list. The stylesheet node-set.xsl supplies the missing nodes in a result tree fragment, as shown in Example 15-4.

Example 15-4. Using the Xalan nodeset function to convert result tree fragments into node-sets
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xalan" exclude-result-prefixes="xalan"> <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="xalan:nodeset($frag)/python/*"/>   <xsl:apply-templates select="escape"/>  </xsl:copy> </xsl:template>     <xsl:template match="escape">  <xsl:copy-of select="."/> </xsl:template>     </xsl:stylesheet>

The Xalan namespace and prefix are set up for use on the stylesheet element. Following that is a variable definition that contains a result tree fragment. It contains the Python string escapes missing from escapes.xml.

In the template matching python, the python element is copied into the result tree from the source tree, then copy-of uses xalan:node-set( ) in an expression to copy the result tree fragment with the node-set. Yes, copy-of could copy a result tree fragment into the result tree, but xalan:node-set( ) allows you to manipulate the fragment as a node-set. That's why it's possible to follow the function call with the XPath location steps /python/*, which grabs all the escape children in the fragment.

Although the function is called xalan:node-set( ), and the type of object the function returns is a node-set, the node-set that a result tree fragment contains is always a single root node, no matter what processor or extension you use. In this example, the python element is a child of this root node in the fragment. To demonstrate this, try doing count(xalan:node-set($frag)) the result will be 1, regardless of the contents of the fragment.


The second template copies all the escape nodes in the source tree into the result tree, joining them with nodes cast from frag. The following command:

xalan -i 2 escapes.xml node-set.xsl

gives you this combined output:

<?xml version="1.0" encoding="UTF-8"?> <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>   <escape purpose="bell">\a</escape>   <escape purpose="backspace">\b</escape>   <escape purpose="formfeed">\f</escape>   <escape purpose="newline">\n</escape>   <escape purpose="carriage return">\r</escape>   <escape purpose="horizontal tab">\t</escape>   <escape purpose="vertical tab">\v</escape> </python>

That's an example of a Xalan function; now, I'll demonstrate an EXSLT function.



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