Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
The answer the working group came up with is to invoke magic (or, in the phrase that was used at the time, a “winged horse”). The practical reality is that in many cases the XPath processor will have a fairly intimate relationship with the XML parser and/or the XML schema validator. In such cases, the XPath processor probably has access to all the schema information that was used when validating the document. It would be very difficult to formalize all this information as part of the evaluation context, so all that the specification says is that if such information is available, the XPath processor can use it to evaluate expressions like this. If the information isn't available, then the document must be rejected.
There are very many different scenarios for how documents are parsed, validated, and queried. In a typical XSLT environment, the parsing and validation usually happen just before the transformation starts. In an XML database, however, parsing and validation happen when the document is loaded into the database, which may be months or years before the query is executed. The XPath specification tries to cope with this variety of different usage scenarios, but in doing so, it inevitably leaves some aspects of the language implementation-defined.
You can avoid these problems by explicitly importing all the schemas that are used to validate documents used by your XPath expressions.
In-Scope Variables
The static context for an XPath expression includes a list of the variables that can be referenced. The information available at this time includes the name of the variable and its type, but not the actual value. It's up to the host language how these variables are declared: in XSLT, for example, they are declared using
adds a variable with name
start
and type
xs:integer?
to the static context of every XPath expression in the stylesheet.
The name of a variable is a QName: that is, it contains a namespace URI and a local name. In practice, it's quite unusual to put variables in a namespace, but it is permitted. It's more common to see this with XQuery, which associates namespaces with modules, so that variables exported by a module will carry the namespace of that module.
It is an error for the XPath expression to refer to variables that aren't present in the static context. In a system that does static type checking, it's also a static error to use a variable in a way that is inconsistent with its type. In systems that do dynamic type checking (which will usually be the case for XSLT), such errors are reported only if they occur when the XPath expression is evaluated.
This aspect of the static context differs from all the other aspects in that it can vary for different parts of a single XPath expression. The static context for a nested subexpression may include variables declared in containing
for
,
some
, or
every
expressions, as well as the variables made available by the host language. The XPath expressions that declare new variables are all listed in Chapter 8.
In-Scope Functions
The static context for an XPath expression also includes a list of the functions that can be called from within the expression. Each function is identified uniquely by its name (a QName, containing a namespace URI and local name) together with its
arity
, which is an integer indicating how many parameters the function has. Two functions with the same name but different numbers of parameters are regarded as being completely distinct functions.
The information that's needed about each function at compile time, apart from the name and arity, is the function signature. The function signature defines the type of each of the function's parameters, as well as the type of its result. This information enables the XPath processor to decide at compile time whether a function call is legitimate: it can check, firstly, that a function with the right name and number of arguments actually exists, and secondly, (if the processor does static type checking) that the arguments are each of the correct type. Even when the processor doesn't do static type checking, the signature is useful for optimization, because it enables the processor to generate code to convert the supplied values to the required type.