Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
This option is not one that you will need to use very often, but it is there for completeness. If you want to interpret a link relative to the stylesheet, you can write, for example:
document(@href, document(“”))
This works because the second argument returns the root node of the stylesheet, which is then used as the base URI for the relative reference contained in the
href
attribute.
With the extended function library that XPath 2.0 makes available, an alternative is to resolve the relative reference yourself by calling the
resolve-uri()
function, which is described on page 867. This allows you to resolve against any base URI, which does not have to be the base URI of any particular node. I have used this in a situation where the base URI for resolving references was passed as a parameter to the stylesheet.
See Also
id()
on page 802
key()
on page 812
resolve-uri()
on page 867
document-uri
The
document-uri()
function returns a URI associated with a document node.
Signature
Argument | Type | Meaning |
input | node()? | The document node whose URI is required. If the node is not a document node, or if an empty sequence is supplied, the empty sequence is returned. |
Result | xs:string? | The URI of the document node . |
Effect
The URI that is returned is always an absolute URI, and it has the property that if you passed it as an argument to the
doc()
function, you would get the input node back.
If no absolute URI is known for the supplied document node, the empty sequence is returned.
Usage
This function is provided to allow a reference to a particular document to be constructed, either in the result document of an XSLT transformation, or simply in error messages. It is particularly useful where the transformation is processing a large batch of similar input documents, accessed perhaps using the
collection()
function, or perhaps supplied as a parameter to the transformation or query in a global variable.
To take an XSLT example, you might be producing a result document that acts as an index to a collection of input documents. This might include code such as:
See Also
base-uri()
on page 719
collection()
on page 726
doc()
on page 750
element-available
This function is available in XSLT only
.
This function is used to test whether a particular XSLT instruction or extension element is available for use.
For example, the expression
element-available(‘xsl:text’)
returns
true
.
Changes in 2.0
None.
Signature
Argument | Type | Meaning |
name | xs:string | The name of the element being tested. The string must take the form of a lexical QName . |
Result | xs:boolean | true if the named element is available for use as an instruction , false otherwise. |
Effect
The first argument must take the form of a lexical
QName
: that is, an XML name with an optional namespace prefix that corresponds to a namespace declaration that is in scope at the point in the stylesheet where the
element-available()
function is called.
If this namespace declaration identifies the XSLT namespace
http://www.w3.org/1999/XSL/Transform
, then the function returns
true
if the name is the name of an XSLT-defined
instruction
, and
false
otherwise.
The instructions defined in XSLT 1.0 were as follows.
In the XSLT 2.0 specification, several new instructions have been added to this list.
Instructions are XSLT elements that can appear directly within a sequence constructor. Top-level XSLT declarations such as
false
(but don't rely on it: at least one popular processor, Microsoft MSXML3, returns
true
for all XSLT elements). Similarly, elements such as
If the prefix of the
QName
identifies any namespace other than the XSLT namespace, then the function returns
true
if and only if the XSLT processor has an implementation available for the named instruction: that is, if this element can be used as an extension instruction in a sequence constructor, rather than being treated simply as a literal result element.
Note that the result of the
element-available()
function does not depend on whether the namespace has been designated as an extension namespace by using the
[xsl:]extension-element-prefixes
attribute. If the XSLT processor has an implementation of the instruction available, the function should return
true
whether or not it is currently in a designated extension namespace.
If the
QName
has no prefix, the default namespace (declared using
xmlns=“some.uri”
) is used. This is one of the few cases where this happens, and the reason is that the name is always an element name: the default namespace applies only to elements.
However, if the
QName
expands to a name with a null namespace URI, the result of the function will always be false. This is because both XSLT instructions and extension elements will always have a non-null namespace URI.
In principle, you can construct the value of the argument as a runtime expression, rather than supplying it as a string literal. I can't think of any possible reason why it might be useful to do this, but implementors have to allow for the possibility.
Usage and Examples
There are two ways to use this function: it can be used to test for XSLT elements introduced in a later version of XSLT, and it can be used to test for the presence of vendor or third-party extensions.
Testing for Features Available in Later XSLT Versions
This function was introduced in XSLT 1.0, but it becomes useful only now that version 2.0 of the specification is available. As we've seen, the XSLT 2.0 specification introduces several new instructions. If you want to use an instruction such as
use-when
attribute to avoid executing it, or use the
So why was the function specified as part of version 1.0? The answer is obvious when you think about it: you want to write a stylesheet that uses version 2.0 features, so you call
element-available()
in order to fail gracefully if you're running with an XSLT processor that supports version 1.0 features only. However, this will work only if the version 1.0 XSLT processor supports the
element-available()
function, which is why it was specified from the start. This is an unusually thoughtful piece of forward planning: the XSLT designers didn't want to get into the same kind of forward-compatibility problems that have bedeviled HTML. Of course, it still means that if you want your stylesheet to run with XSLT processors that support different levels of the language, you will have to write and test conditional code in your stylesheet, but at least the capability is there.
In principle, you can test whether a version 1.0 instruction is available on the basis that there may be subset implementations around; unfortunately, this will work only if the subset implementation includes the
element-available()
function, which is not guaranteed; it tends to be one of the things that implementors leave till last.
It's tempting to use the
use-when
attribute to mask XSLT 2.0 code from XSLT 1.0 processors. This doesn't work, unfortunately, as
use-when
is a 2.0 facility, and 1.0 processors won't recognize it.
Note that if you write a stylesheet that uses features defined in XSLT version 2.0, and if you want to run it with an XSLT 1.0 processor, then you must specify
version=“2.0”
on the
xsl:version=“2.0”
on some literal result element, even if you write an
element-available()
to avoid executing the relevant code. If you specify
version=“1.0”
, then any use of new XSLT 2.0 elements is flagged as an error even if the code is never executed.