Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
There is no way of finding out at runtime what the types of the arguments should be, which means that knowing a function is available is not enough to ensure that any given call on the function will be successful.
The functions that are considered to be available are those in the static context of the XPath expression containing the call on
function-available()
. If
function-available()
is evaluated from the
use-when
attribute, this includes core XPath and XSLT functions, constructor functions for built-in types, and extension functions. If
function-available()
is evaluated during stylesheet execution, it also includes stylesheet functions (defined using
Usage
There are two ways of using
function-available()
: it can be used to achieve backward compatibility when using standard functions defined after version 1.0 of the specification, and it can be used to test for the presence of vendor or third-party extensions.
The ability to test for the existence of stylesheet functions is not particularly useful, especially as this cannot be done within a
use-when
attribute (it will always return false, because stylesheet functions are not present in the static context for evaluating
use-when
).
Testing for the Existence of System-Defined Functions
The ability to test whether a particular system-defined function is available was not especially useful with version 1.0 of the specification. It was designed to come into its own when later versions of the specification were published. If you want to use a function that is newly defined in version 2.0, then you can test to see whether it is available with a particular XSLT processor, before using it. If it is not available, you can use
forward-compatible mode
by setting the
version
attribute on the
“2.0”
, a conformant XSLT 1.0 processor should not object to the presence of an expression in your stylesheet that calls an unknown function, unless the expression is actually executed.
For example, the function
current-date()
becomes available in XPath 2.0. You can test for its existence by writing:
For a fuller example, see the end of this section.
In theory, you could test whether a function such as
current-date()
is available by calling
system-property(‘xsl-version’)
and testing whether the result is equal to
2.0
. But the reality is that there will be processors that have implemented some of the XPath 2.0 functions but not yet all of them. A processor isn't supposed to return
2.0
as the value of
system-property(‘xsl:version’)
unless it is a fully conformant XSLT 2.0 processor; but if it isn't a fully conformant processor, then by definition you can't be sure whether it follows the rules. So it's better to use the finer-grained check offered by
function-available()
.
Testing for Vendor or Third-Party Extensions
The second way of using
function-available()
is to test for vendor or third-party extensions. If you know that a particular extension function is present in some implementations and not others, you can use the
function-available()
test to see whether it is present, and use the new
use-when
attribute to handle the situation when it isn't.
The
use-when
attribute provides a way of conditionally including or excluding parts of a stylesheet at compile time, based on a compile-time condition. There are more details of this feature on page 127 in Chapter 3. The compile-time condition is an XPath expression, restricted to operate with a very limited context, which means that it can only access information known at compile time. It cannot, for example, access a source document, or refer to variables. But the context does include the set of extension functions that are available. This is illustrated in the example that follows.
Example 1: Testing for xx:node-set() Extensions
The XSLT 2.0 working draft allows you to use a temporary tree (the value constructed when an
xt:node-set()
or
msxml:node-set()
). If you want to write a stylesheet that is as portable as possible, you need to write code that discovers which of these facilities is available.
Stylesheet
The following stylesheet (
node-set-available.xsl
) contains a named template that takes a temporary tree as a parameter and calls
node-set()
extension functions is available, and uses that.
xmlns:xsl=“http://www.w3.org/1999/XSL/Transform”
version=“2.0”>
xmlns:msxml=“urn:schemas-microsoft-com:xslt”
xmlns:xt=“http://www.jclark.com/xt”
xmlns:saxon6=“ http://icl.com/saxon”>
select=“$fragment”/>
select=“msxml:node-set($fragment)”/>
select=“xt:node-set($fragment)”/>
select=“saxon6:node-set($fragment)”/>
Cannot convert result tree fragment to node-set
This named template can be called as follows, to process all the nodes in the result tree fragment.
The logic here is slightly tortuous. You need to look at it in two different ways: as an XSLT 1.0 stylesheet, and as a 2.0 stylesheet.
As a 1.0 stylesheet, the outer
use-when
attribute on the
version=“2.0”
, and in forward-compatible mode, unknown attributes on XSLT elements are ignored. The 1.0 processor then takes one of the branches of the inner
xx:node-set()
extension functions is available.
As an XSLT 2.0 stylesheet, the outer
use-when
condition. The
use-when
condition is necessary, because an XSLT 2.0 processor would otherwise report a static (compile time) error when it sees an XPath expression that calls an unknown function such as
saxon6:node-set()
, even though the function is not actually evaluated at runtime.
When this example is run with an XSLT 2.0 processor, it doesn't actually invoke the
function- available()
function—which arguably makes it a poor choice of example for this section. The next example attempts to remedy this.