Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
. Such uncertainty causes havoc with query languages, and so XPath took a different approach. Instead of interpreting the absence of a timezone as meaning that the timezone is unknown, it interprets it as meaning that an implicit timezone should be assumed. Where possible, this will be the timezone in the place where the user is located, or failing that, the timezone in the place where the computer is located. However, XPath doesn't worry itself with how the implicit timezone is set up: it simply says that there is one, leaves it to the host environment to initialize it, and goes on to specify how it is used when performing operations on dates and times.
Some host languages might choose to specify how the implicit timezone is initialized: in Java, for example, it could have a defined relationship to the current locale. XSLT, however, chooses to pass the buck to the implementation. It's likely that many implementations will use the timezone setting from the computer on which the XSLT processor is running, which may or may not give useful results.
The implicit timezone is used behind the scenes by a number of operators that manipulate dates and times, but it is also available explicitly to the XPath user through the function
implicit-timezone()
, which is included in Chapter 13.
Available Documents and Collections
One of the aims in defining the evaluation context for XPath is to list all the things in the environment that can affect the result of an XPath expression. Two of the most environment-dependent constructs in the language are the
doc()
function (and its XSLT precursor,
document()
), which loads a document using a URI, and the
collection()
function, which similarly identifies a collection of documents using a URI.
In the XSLT 1.0 specification there was a fairly detailed description of how the
document()
function was supposed to work. It described in some detail the process of URI resolution, the way in which the URI was dereferenced to fetch a resource from the Web, the requirement for this resource to contain well-formed XML, and the way that the media type of the resource affected the interpretation of any fragment identifier in the URI.
But at the same time, the specification said that the input to the XSLT processor was a tree, following the rules in the data model, and that nothing in the specification should constrain the way in which the tree was constructed.
There's clearly a tension between these two definitions, and this revealed itself, during the life of the specification, in some practical problems. Notoriously, the Microsoft XSLT processor took the second statement at face value, and stripped spaces from the source document by default, which meant that it often produced different results from other XSLT processors. Another XSLT processor decided to expand XInclude directives in the source document by default. Both of these decisions were entirely conformant according to the specification, and yet they led to practical interoperability problems.
Even more extreme effects can be achieved by exploiting the
URIResolver
interface in the Java JAXP API (which Microsoft has emulated in the
System.Xml
framework classes under the name
XmlResolver
). This allows the user to nominate a routine that will intercept all requests for a URI from the
doc()
function, and take over the job of delivering a document in response to the request. This means, for example, that you can call the
doc()
function with the URI
special://prime/100
and return a document containing the first 100 prime numbers, constructed algorithmically. This mechanism is undoubtedly useful, but it rather makes a mockery of any detailed description in the language specification of how the
doc()
function is supposed to work.
Rather than try and tighten up the specs to force interoperability, the working groups decided that this was a place where allowing implementations some freedom was actually in users' best interests. The way that this is reflected in the spec may seem a little confusing. It simply says that the dynamic context of an XPath expression provides a mapping from URIs onto document nodes. The easiest way to read this is by thinking of the mapping as being an external function rather like the Java
URIResolver
: if you give it a URI, it comes back with a document node. This function might go out to the Web, retrieve an XML document, parse it, validate it, and turn it into a tree in the data model. Or, it might return a document node that represents a virtual document, which is actually a collection of data in a relational database. Or, it might construct an XML document containing the first 100 prime numbers. Quite simply, any thing goes.
So you can't be sure that the same call on the
doc()
function will produce the same results on two different implementations. The hope is that market forces will ensure that most products support the obvious mappings from URIs to documents, even though these mappings are no longer mandatory, and might not be provided by XPath processors designed to operate in specialized environments.
As well as the
doc()
function which returns a document node corresponding to a URI, XPath 2.0 also provides the
collection()
function which returns a collection of documents (actually, a sequence). While there is a great deal of precedent and user expectation for the way in which URIs will map to individual documents, there is very little precedent for the concept of a document collection identified by URI, and it's likely therefore that different processors will interpret this concept in very different ways. There is a tendency, however, for good ideas to be copied from one implementation to another, so perhaps conventions will start to appear. However, the concept of collections is really intended as an abstraction of an XML database, or part of an XML database, and since the system architecture of different XML databases is highly variable, there might well remain radical differences in the way that the concept of a collection is realized.
As with other aspects of the context, the host language gets a say in the matter. For example, a host language could say that the set of available documents and collections is always empty, and thus constrain XPath expressions to operate on a single document, or on documents accessible through variables. Indeed, the current draft of XML Schema 1.1, which uses XPath expressions to define assertions, does just this. But in the case of XSLT, little more is said on the subject. The only thing that XSLT adds is a specification of the
document()
function, which continues to be available in XSLT and is now defined in terms of the simpler XPath 2.0
doc()
function.
Summary
XPath expressions are used in XSLT to select data from the source document and to manipulate it to generate data to place in the result document. XPath expressions play the same role for XML as the SQL
SELECT
statement plays for relational databases—they allow us to select specific parts of the document for transformation, so that we can achieve the required output. Their use is not restricted to XSLT stylesheets—they can also be used with XPointers to define hyperlinks between documents, and many DOM implementations allow XPath expressions to be used to find nodes within the DOM.
This chapter provided an introduction to the basic constructs in XPath expression: an overview of the grammar and the lexical rules, and explanation of some of the basic constructs such as literals, variable references, function calls, and conditional expressions.
In this chapter we also described all the contents of the XPath evaluation context, including both the static and the dynamic context. The context is important because it establishes the interface between XPath and a host language such as XSLT, and it identifies all the external information that may affect the result of an XPath expression.
The next four chapters explore the XPath language in more depth. Chapter 8 looks at the basic operators for arithmetic, boolean comparisons, and testing identity and ordering of nodes. Chapter 9 describes path expressions and the operations for combining sets of nodes to form their union, intersection, or difference. Chapter 10 examines expressions on sequences, notably the
for
expression, which provides a general mapping capability to construct one sequence by applying an expression to each item of an input sequence. Then, Chapter 11 discusses operations on types.
After a return to XSLT to describe match patterns in Chapter 12, Chapter 13 provides a catalog of all the functions in the core library, and Chapter 14 gives the syntax for regular expressions, which are used in three of these functions.
Chapter 8
XPath: Operators on Items
This chapter defines the simple operators available for use in XPath expressions. This is inevitably a rather arbitrary category, but these operators seem to have enough in common to justify putting them together in one chapter. All these operators return single items (as distinct from sequences)—in fact, all of them except the arithmetic operators in the first section return a boolean result.
More specifically, this chapter describes the following families of operators: