There are two aspects to the context: the static context, which depends only on where the expression appears in the stylesheet; and the dynamic context, which depends on the state of processing at the time the expression is evaluated.
The static context for an expression includes the following:
- The set of namespace declarations in force at the point where the expression is written. This determines the validity and meaning of any namespace prefixes used in the expression. As well as defining the namespace prefixes that are available, the context also defines the default namespace that will be used for unqualified element names appearing in path expressions.
- The set of variable declarations (that is,
and
elements) in scope at the point where the expression is written. This determines the validity of any variable references used in the expression. As well as checking at compile time that the variable has been declared, the processor can also make checks on its type; for example, it would be an error to use a variable of type
xs:date
as an argument to the
round()
function, and the processor can often detect such errors and report them at compile time.
- The functions that are available to be called. These always include the core library of functions defined in the XSLT and XPath specifications, and the constructor functions for built-in atomic types such as
xs:date
. They also include user-defined functions written using the
declaration, constructor functions for user-defined types in an imported schema (as described in Chapter 4), vendor-defined extension functions, and user-defined extension functions linked in to the stylesheet using vendor-defined mechanisms.
- The base URI of the stylesheet element containing the XPath expression. This only affects the result if the expression uses functions such as
document()
that make explicit use of the base URI.
All of these aspects of the static context for XPath expressions can be controlled from within the stylesheet, and may be different for different XPath expressions. There are other aspects of the XPath context that cannot be controlled using XSLT itself, but where implementors are likely to allow you some control via the API of their individual products. The most important example in this category is the set of URIs that are available for identifying collations (that is, rules for sorting and comparing strings according to the conventions of different languages).
The dynamic context is set only at stylesheet execution time. It consists of the following:
- The current values of all the variables that are in scope for the expression. These may be different each time the expression is evaluated.
- The focus, which reflects the current state of processing in the stylesheet. The focus comprises the following:
- The
context item
. This is the item (often a node in the source tree) that is currently being processed. An item becomes the context item when it is selected using the
or
instructions. The context item can also be set by the XPath processor when evaluating a subexpression. The context item can be referenced using the expression
.
. In addition, the
current()
function (defined in Chapter 13) can always be used to reference the item that's the context item at the XSLT level, ignoring any changes made at the XPath level.
- The
context position
. This is an integer (≥1) that indicates the position of the context item in the sequence of items currently being processed. The context position can be referenced using the
position()
function. When
or
are used to process a sequence of items, the context position takes the values 1 . . .
n
as each of the items in the list is processed. Similarly, when a predicate is used within a path expression, the context position is the position of the node being tested within the set of nodes being tested. For example,
child::a[position() !=1]
selects all the child elements named
, except the first.
- The
context size
. This is an integer (≥1) that indicates the number of items in the sequence of items currently being processed (that is, the highest value that
position()
will reach). The context size can be referenced using the
last()
function. For example,
child::a [position() !=last()]
selects all the child elements named
, except the last.
- The set of documents that can be accessed using the
doc()
and
document()
functions is also regarded as being part of the dynamic context. This might include the whole of the Web, or it might be restricted by security policies to the server from which the stylesheet was loaded, or (if, say, the transformation is running on an embedded processor controlling the engine of your car) it might contain no documents at all. Modeling the set of addressable documents as part of the context is a formal device for describing the language semantics (it's a way of saying that the result of the
document()
function is defined by the environment in which the stylesheet runs, not by the language specification itself), and it turns out to be quite a neat device for distinguishing those aspects of these functions that are defined by the language spec from those that depend on the implementation.
Some system functions that can be used in XPath 2.0 expressions have other dependencies on the stylesheet context; for example, the effect of the
key()
function depends on the set of
declarations in force; but the list given earlier covers all the context information that is directly accessible to user-written expressions.
Temporary Documents
As we described at the beginning of the chapter, a transformation takes a source tree as input (or perhaps more than one source tree) and produces a result tree (or several result trees) as output.
Very often, however, the easiest way to write a complex transformation is to split it into a number of phases, each of which performs one task. Like pipes in Unix, this creates a powerful way of reusing modules of code—on the basis that each module does only one job. For example, if your stylesheet involves selecting input records, sorting them, grouping them, numbering them, and then formatting the result as HTML, you could potentially carry out each of these five steps in a separate transformation phase. One benefit is that if you wanted to change the output from HTML to PDF, the first four steps would be completely reusable.
One way of doing this is to write five separate stylesheets, and couple them together into a processing pipeline. This can be done using the Java JAXP API, described in Appendix D, or by using the new XProc pipeline language being developed by W3C. You can even do it (less efficiently) with a shell script or using
ant
. But often, you want rather closer coupling than this. So the alternative is to write all the phases of the transformation in a single stylesheet, using
temporary documents
to represent the intermediate results between one phase of processing and the next.
A temporary document is created by using an
element with no
as
attribute, containing a sequence constructor to create the content of the tree. For example: