XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (311 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
3.6Mb size Format: txt, pdf, ePub

Although the XPath 1.0 type system also included a boolean data type, there is no special treatment of
xs:boolean
in the backward-compatibility rules. That's because the only XPath 1.0 function that actually expected a boolean argument was the
not()
function, and this function in XPath 2.0 has been defined in a way that is fully backward compatible.

XPath 1.0 never defined any rules for calling external user-defined functions, so backward compatibility in that area is entirely a matter for implementors.

Side Effects

None of the standard functions have side effects; they don't change the values of variables, they don't produce any output, and they don't change any settings in the browser or the operating system. They don't even create any new nodes, though both XSLT and XQuery allow you to write functions that can be called from XPath to create new nodes.

There is nothing to stop an extension function from having side effects; for example, an extension function could print a message or increment a counter, or even do something more radical such as modify the source document or the stylesheet itself. However, extension functions with side effects are likely to be rather unpredictable, since there is nothing to say in which order things happen. For example, you can't assume that global variables in XSLT are evaluated in any particular order or that they are evaluated only once, and a global variable that is never accessed might never be evaluated at all.

Functions can have side effects even if you think of them as read-only. You might imagine that if you write an extension function
ext:read()
that reads a line of input from the console, then the expression
(ext:read(),
ext:read())
will read two lines, and return them in order. You could be in for a surprise. The system might read two lines, and return them out of order; or it might read a single line, and return two copies of it. This happens because calling the
ext:read()
function has the side effect of changing the current reading position in a file connection. Implementations might try to be more helpful than this, but you can't rely on it.

The closest that the standard library comes to a function with side effects is the
trace()
function, which is supposed to produce diagnostic output. Like other functions in the standard library, this is described in Chapter 13. However, the specification gives so much latitude in terms of the way this is implemented that it would be quite legitimate for an implementation to do nothing when it encounters this function call. You might well find that with an optimizing processor, the output produced by multiple calls on the
trace()
function bears very little relationship to the expected order of execution.

The formal semantics of the language does try to deal with functions that create new nodes in a sanitary way. XPath itself, when confined to the standard function library, is a read-only language, but both XSLT and XQuery do allow functions that create and return new nodes. For example, in XSLT:


  


or in XQuery:

declare function f:make() as element() {

  

};

These functions create all sorts of complexities in the language semantics: for example, it is no longer possible to take a function call out of a loop and execute it once only. It also means that the expression
f:make()
is f:make()
is false. Frankly, in XSLT stylesheets I would advise against writing such functions—I think it's good coding practice in XSLT to use XSLT instructions and templates when creating nodes in the result tree, and to use XPath expressions and functions when reading information from the source tree. XQuery doesn't have this distinction between instructions and expressions, so the same function mechanism has to serve both purposes. But you need to use it with care.

Examples

These examples are in the file
function-calls.xsl
, but you will probably need to edit the file before running it, as it uses an extension function that is available only in James Clark's xt processor.

Expression
Description
true()
A call on a standard function that always returns the
xs:boolean
value
true
.
string-length($x)
A call on a standard function that expects a string, and returns the number of characters it contains. The actual value supplied can be a node, provided its type is either
xs:string
or
xs:untypedAtomic.
If
$x
is a non-string value, such as an
xs:anyURI
, a type error occurs, unless you are running in backward-compatibility mode.
count(*)
A call on a standard function that evaluates the path expression
*
(which returns all element children of the context node) and returns a number indicating how many nodes there are in this sequence.
xt:intersection ($x,$y)
A call on an extension function. It is identified as an extension function by the presence of a prefix
xt:
, which must correspond to a namespace declaration that is in scope. The rules for locating an implementation of this extension function are implementor-defined.

Conditional Expressions

A conditional expression corresponds to the
if..then..else
construct found in almost every programming language. A condition is evaluated, and based on the result, the expression returns the result of evaluating either the
then
or the
else
branch.

Other books

Defy Not the Heart by Johanna Lindsey
Birchwood by John Banville
The Cinderella List by Judy Baer
The Perfect Mistress by Betina Krahn
Dead Weight by Lori Avocato
All That Man Is by David Szalay
The Mind Pool by Charles Sheffield
Love Rewards The Brave by Monroe, Anya