Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
The scope of a global variable is the entire stylesheet, including any stylesheets that are included or imported. A global variable may even be referenced before it is declared. The only constraint is that circular definitions are not allowed; if variable
x
is defined in terms of
y
, then
y
may not be defined directly or indirectly in terms of
x
.
The scope of a local variable is block-structured; it may be referenced in any following sibling element or in a descendant of a following sibling. This is illustrated in
Figure 6-16
.
The diagram shows, for a variable X, the elements that may contain a reference to X; the shaded elements may refer to X, and the unshaded elements may not. Specifically, a local variable may be referenced in any following sibling element, or in a descendant of a following sibling. It cannot be referenced within its own descendants, and it goes out of scope when the end tag for its parent element is encountered. Unlike global variables, a forward reference to a local variable is not allowed. If you think of XSLT instructions as being like the statements in a block-structured language such as C, Java, or JavaScript, and the enclosing element as being like a block enclosed in these languages by curly braces, the scope rules will seem very familiar.
Two global variables may have the same name only if they have different
import precedence
; in other words, if one of them was in an imported stylesheet (for further details, see
XSLT 1.0 did not allow a local variable to be defined with the same name as another local variable already in scope. This restriction was there as a way of detecting user errors. The restriction has gone in XSLT 2.0, although there is still a warning in the specification advising that this isn't good practice. In fact, not all XSLT 1.0 processors actually enforced this rule. If a variable reference is used when two or more variables with the matching name are in scope, then the reference is taken to refer to the one whose scope is smallest.
This principle extends to variables declared within an XPath expression. To take an extreme example, it is legal to write:
The output of the template will be
A
+
B
+
C
+
D
+
.
These rules on uniqueness and scope of names apply equally to parameters declared using
The Value of the Variable
The value of the variable may be given either by the XPath expression in the
select
attribute, or by the contents of the contained sequence constructor. If there is a
select
attribute, the
select
attribute and the sequence constructor is empty, the value of the variable is a zero-length string, unless there is an
as
attribute, in which case the value is an empty sequence (assuming that the
as
attribute permits an empty sequence).
Figure 6-17
summarizes the different ways of specifying the value. The numbers in brackets refer to the numbered paragraphs below that explain the option in more detail.
1.
The following example declares a parameter whose default value is a zero-length string:
Again, this option is not useful for variables, but it can be useful with
2.
If a sequence constructor is used with no
as
attribute, a temporary document is constructed. This is done by creating a new document node and using the value of the result sequence to form the children of the document node. The detailed rules for constructing the content of the document node are the same as those for the
Here the value of the variable is a document node, whose only child is a
element, which in turn has four
3.
If the
select
attribute is provided without an
as
attribute, the effect is the same as if
as=“item()*”
were specified: no type checking or conversion takes place, and the value may be of any type. For example:
Here the value of the
select
attribute is again of type
xs:double
, but for a different reason: it was written as a double literal, and no conversion has taken place.
4.
The following example declares a parameter whose default value is an empty sequence:
This option is not very useful for variables, but it can be useful with
5.
If a sequence constructor is used with an
as
attribute, the instructions in the sequence constructor are evaluated. The result sequence is checked against the type specified in the
as
attribute and is converted if necessary using the standard conversion rules described on page 505. An error is reported if the conversion is not possible. The processor may report this as a compile-time error if it can tell at compile time that the value of the expression will never be convertible to the required type. For example:
Here the sequence constructor returns a single text node. The contents of this text node are converted to an integer, which becomes the value of the variable.
6.
If the
select
attribute is provided, its value must be an XPath expression. This expression is evaluated. The value is checked against the type specified in the
as
attribute and, if necessary, is converted to this type using the standard conversion rules described on page 505. An error occurs if this conversion is not possible. Otherwise, the error will be reported at runtime. For example:
Here the value of the
select
expression is of type
xs:decimal
, but the final value of the variable is an
xs:double
, because the
as
attribute forces a conversion.