item is being processed. This makes xsl:iterate
suitable for tasks
such as creating a running total over a sequence of financial
transactions.
A further difference is that xsl:for-each
permits sorting
of the input sequence, while xsl:iterate
does not.
xsl:for-each
instruction<!-- Category: instruction
-->
<xsl:for-each
select = expression >
<!-- Content: (xsl:sort*, sequence-constructor)
-->
</xsl:for-each>
The xsl:for-each
instruction processes each item in a sequence of items, evaluating
the sequence constructor within the
xsl:for-each
instruction once for each item in that sequence.
The select
attribute is required; it contains an expression which is evaluated
to produce a sequence, called the input sequence. If there is an
xsl:sort
element present
(see 13 Sorting) the input sequence
is sorted to produce a sorted sequence. Otherwise, the sorted
sequence is the same as the input sequence.
The xsl:for-each
instruction contains a sequence constructor.
The sequence constructor is evaluated
once for each item in the sorted sequence, with the focus set as
follows:
The context item is the item being processed.
The context position is the position of this item in the sorted sequence.
The context size is the size of the sorted sequence (which is the same as the size of the input sequence).
For each item in the input sequence, evaluating the sequence constructor produces a
sequence of items (see 5.8
Sequence Constructors). These output sequences are
concatenated; if item Q follows item P in the
sorted sequence, then the result of evaluating the sequence
constructor with Q as the context item is concatenated
after the result of evaluating the sequence constructor with
P as the context item. The result of the xsl:for-each
instruction is
the concatenated sequence of items.
xsl:for-each
For example, given an XML document with this structure
<customers> <customer> <name>...</name> <order>...</order> <order>...</order> </customer> <customer> <name>...</name> <order>...</order> <order>...</order> </customer> </customers>
the following would create an HTML document containing a table
with a row for each customer
element
<xsl:template match="/"> <html> <head> <title>Customers</title> </head> <body> <table> <tbody> <xsl:for-each select="customers/customer"> <tr> <th> <xsl:apply-templates select="name"/> </th> <xsl:for-each select="order"> <td> <xsl:apply-templates/> </td> </xsl:for-each> </tr> </xsl:for-each> </tbody> </table> </body> </html> </xsl:template>
xsl:iterate
Instruction<!-- Category: instruction
-->
<xsl:iterate
select = expression >
<!-- Content: (xsl:param*, sequence-constructor,
xsl:on-completion?)
-->
</xsl:iterate>
<!-- Category: instruction
-->
<xsl:next-iteration>
<!-- Content: (xsl:with-param*) -->
</xsl:next-iteration>
<!-- Category: instruction
-->
<xsl:break
select? = expression >
<!-- Content: (sequence-constructor)
-->
</xsl:break>
<xsl:on-completion
select? = expression >
<!-- Content: (sequence-constructor)
-->
</xsl:on-completion>
The select
attribute is required; it contains an expression which is evaluated
to produce a sequence, called the input sequence.
The sequence constructor contained in
the xsl:iterate
instruction is evaluated once for each item in the input sequence,
in order, or until the loop exits by evaluating an xsl:break
instruction, whichever
is earlier. Within the sequence constructor
that forms the body of the xsl:iterate
instruction, the
context item is set to each item from the
value of the select
expression in turn; the context position reflects the position
of this item in the input sequence, and the context size is the
number of items in the input sequence (which may be greater than
the number of iterations, if the loop exits prematurely using
xsl:break
).
Note:
If xsl:iterate
is
used in conjunction with xsl:stream
to achieve streaming,
calls on the function last
FO30
will be disallowed.
The xsl:break
and
xsl:on-completion
elements may have either a select
attribute or a
non-empty contained sequence constructor but not
both. The effect of the element in both cases is obtained by
evaluating the select
expression if present or the
contained sequence constructor otherwise; if neither is present,
the value is an empty sequence.
The effect of xsl:next-iteration
is to
cause the iteration to continue by processing the next item in the
input sequence, potentially with different values for the iteration
parameters. The effect of xsl:break
is to cause the
iteration to finish, whether or not all the items in the input
sequence have been processed. In both cases the affected iteration
is the one controlled by the innermost ancestor xsl:iterate
element.
The instructions xsl:next-iteration
and
xsl:break
are allowed
only as descendants of an xsl:iterate
instruction, and
only in a tail position within the sequence constructor forming the
body of the xsl:iterate
instruction.
[Definition: An instruction J is in a tail position within a sequence constructor SC if it satisfies one of the following conditions:]
J is the last instruction in SC, ignoring
any xsl:fallback
instructions.
J is in a tail position within the sequence
constructor that forms the body of an xsl:if
instruction that is itself in
a tail position within SC.
J is in a tail position within the sequence
constructor that forms the body of an xsl:when
or xsl:otherwise
branch of an
xsl:choose
instruction
that is itself in a tail position within SC.
J is in a tail position within the sequence
constructor that forms the body of an xsl:try
instruction that is itself
in a tail position within SC (that
is, it is immediately followed by an xsl:catch
element, ignoring any
xsl:fallback
elements).
J is in a tail position within the sequence
constructor that forms the body of an xsl:catch
element within an
xsl:try
instruction that is
itself in a tail position within SC.
[ERR XTSE3120] It is a static error if an
xsl:break
or xsl:next-iteration
element appears other than in a tail position within the
sequence constructor forming the
body of an xsl:iterate
instruction.
[ERR XTSE3125] It is a static error if the
select
attribute of xsl:break
or xsl:on-completion
is
present and the instruction has children.
[ERR XTSE3130] It is a static error if the
name
attribute of an xsl:with-param
child of an
xsl:next-iteration
element does not match the name
attribute of an
xsl:param
child of the
innermost containing xsl:iterate
instruction.
Parameter names in xsl:with-param
must be
unique: [see ERR
XTSE0670].
The result of the xsl:iterate
instruction is the
concatenation of the sequences that result from the repeated
evaluation of the contained sequence constructor,
followed by the sequence that results from evaluating the xsl:break
or xsl:on-completion
element
if any.
Any xsl:param
element
that appears as a child of xsl:iterate
declares a
parameter whose value may vary from one iteration to the next. The
initial value of the parameter is the value obtained according to
the rules given in 9.3 Values of
Variables and Parameters. The dynamic context for
evaluating the initial value of an xsl:param
element is the same as
the dynamic context for evaluating the select
expression of the xsl:iterate
instruction (the
context item is thus not the first item in the input
sequence).
On the first iteration a parameter always takes its initial value (which may depend on variables or other aspects of the dynamic context). Subsequently:
If an xsl:next-iteration
instruction is evaluated, then parameter values for processing the
next item in the input sequence can be set in the xsl:with-param
children of
that instruction; in the absence of an xsl:with-param
element that
names a particular parameter, that parameter will retain its value
from the previous iteration.
If an xsl:break
instruction is evaluated, no further items in the input sequence
are processed.
If neither an xsl:next-iteration
nor
an xsl:break
instruction
is evaluated, then the next item in the input sequence is processed
using parameter values that are unchanged from the previous
iteration.
The xsl:next-iteration
instruction contributes nothing to the result sequence
(technically, it returns an empty sequence). The instruction
supplies parameter values for the next iteration, which are
evaluated according to the rules given in 9.10 Setting Parameter Values; if there
are no further items in the input sequence then it supplies
parameter values for use while evaluating the body of the xsl:on-completion
element
if any.
The xsl:break
instruction indicates that the iteration should terminate without
processing any remaining items from the input sequence. The
select
expression or contained sequence
constructor is evaluated using the same context item, position, and
size as the xsl:break
instruction itself, and the result is appended to the result of the
xsl:iterate
instruction
as a whole.
If neither an xsl:next-iteration
nor
an xsl:break
instruction
is evaluated, the next item in the input sequence is processed with
parameter values unchanged from the previous iteration; if there
are no further items in the input sequence, the iteration
terminates.
The optional xsl:on-completion
element
(which is not technically an instruction and is not technically part
of the sequence constructor) is evaluated
when the input sequence is exhausted. It is not evaluated if the
evaluation is terminated using xsl:break
. During evaluation of
this sequence constructor the context item, position, and size are
absent
(that is, any reference to these values is an error). However, the
values of the parameters to xsl:iterate
are available, and
take the values supplied by the xsl:next-iteration
instruction evaluated while processing the last item in the
sequence.
If the input sequence is empty, then the result of the xsl:iterate
instruction is the
result of evaluating the sequence constructor
forming the body of the xsl:on-completion
element, using the initial values of the xsl:param
elements. If there is
no xsl:on-completion
element, the result is an empty sequence.
Note:
Conceptually, xsl:iterate
behaves like a
tail-recursive function. The xsl:next-iteration
instruction then represents the recursive call, supplying the tail
of the input sequence as an implicit parameter. There are two main
reasons for providing the xsl:iterate
instruction. One is
that many XSLT users find writing recursive functions to be a
difficult skill, and this construct promises to be easier to learn.
The other is that recursive function calls are difficult for an
optimizer to analyze. Because xsl:iterate
is more constrained
than a general-purpose head-tail recursive function, it should be
more amenable to optimization. In particular, when the instruction
is used in conjunction with xsl:stream
, it is designed to
make it easy for the implementation to use streaming techniques,
processing the nodes in an input document sequentially as they are
read, without building the entire document tree in memory.
The examples below use xsl:iterate
in conjunction with
the xsl:stream
instruction. This is not the only way of using xsl:iterate
, but it illustrates
the way in which the two features can be combined to achieve
streaming of a large input document.
xsl:iterate
to Compute
Cumulative TotalsSuppose that the input XML document has this structure
<transactions> <transaction date="2008-09-01" value="12.00"/> <transaction date="2008-09-01" value="8.00"/> <transaction date="2008-09-02" value="-2.00"/> <transaction date="2008-09-02" value="5.00"/> </transactions>
and that the requirement is to transform this to:
<account> <balance date="2008-09-01" value="12.00"/> <balance date="2008-09-01" value="20.00"/> <balance date="2008-09-02" value="18.00"/> <balance date="2008-09-02" value="23.00"/> </account>
This can be achieved using the following code, which is designed to process the transaction file using streaming:
<account> <xsl:stream href="transactions.xml"> <xsl:iterate select="transactions/transaction"> <xsl:param name="balance" select="0.00" as="xs:decimal"/> <xsl:variable name="newBalance" select="$balance + xs:decimal(@value)"/> <balance date="{@date}" value="{$newBalance}"/> <xsl:next-iteration> <xsl:with-param name="balance" select="$newBalance"/> </xsl:next-iteration> </xsl:iterate> </xsl:stream> </account>
The following example modifies this by only outputting the information for the first day's transactions:
<account> <xsl:stream href="'transactions.xml"> <xsl:iterate select="transactions/transaction"> <xsl:param name="balance" select="0.00" as="xs:decimal"/> <xsl:param name="prevDate" select="()" as="xs:date?"/> <xsl:variable name="newBalance" select="$balance + xs:decimal(@value)"/> <xsl:variable name="thisDate" select="xs:date(@date)"/> <xsl:choose> <xsl:when test="empty($prevDate) or $thisDate eq $prevDate"> <balance date="{$thisDate}" value="{format-number($newBalance, '0.00')}"/> <xsl:next-iteration> <xsl:with-param name="balance" select="$newBalance"/> <xsl:with-param name="prevDate" select="$thisDate"/> </xsl:next-iteration> </xsl:when> <xsl:otherwise> <xsl:break/> </xsl:otherwise> </xsl:choose> </xsl:iterate> </xsl:stream> </account>
The following code outputs the balance only at the end of each day, together with the final balance:
<account> <xsl:stream href="transactions.xml"> <xsl:iterate select="transactions/transaction"> <xsl:param name="balance" select="0.00" as="xs:decimal"/> <xsl:param name="prevDate" select="()" as="xs:date?"/> <xsl:variable name="newBalance" select="$balance + xs:decimal(@value)"/> <xsl:variable name="thisDate" select="xs:date(@date)"/> <xsl:if test="exists($prevDate) and $thisDate ne $prevDate"> <balance date="{$prevDate}" value="{format-number($balance, '0.00')}"/> </xsl:if> <xsl:next-iteration> <xsl:with-param name="balance" select="$newBalance"/> <xsl:with-param name="prevDate" select="$thisDate"/> </xsl:next-iteration> <xsl:on-completion> <balance date="{$prevDate}" value="{format-number($balance, '0.00')}"/> </xsl:on-completion> </xsl:iterate> </xsl:stream> </account>
If the sequence of transactions is empty, this code outputs a
single element: <balance date=""
value="0.00"/>
.
Problem: Given a sequence of employee
elements,
find the employees having the highest and lowest salary, while
processing each employee only once.
Solution:
<xsl:stream href="employees.xml"> <xsl:iterate select="employees/employee"> <xsl:param name="highest" as="element(employee)*"/> <xsl:param name="lowest" as="element(employee)*"/> <xsl:variable name="is-new-highest" as="xs:boolean" select="empty($highest[@salary ge current()/@salary])"/> <xsl:variable name="is-equal-highest" as="xs:boolean" select="exists($highest[@salary eq current()/@salary])"/> <xsl:variable name="is-new-lowest" as="xs:boolean" select="empty($lowest[@salary le current()/@salary])"/> <xsl:variable name="is-equal-lowest" as="xs:boolean" select="exists($lowest[@salary eq current()/@salary])"/> <xsl:variable name="new-highest-set" as="element(employee)*" select="if ($is-new-highest) then . else if ($is-equal-highest) then ($highest, .) else $highest"/> <xsl:variable name="new-lowest-set" as="element(employee)*" select="if ($is-new-lowest) then . else if ($is-equal-lowest) then ($lowest, .) else $lowest"/> <xsl:next-iteration> <xsl:with-param name="highest" select="$new-highest-set"/> <xsl:with-param name="lowest" select="$new-lowest-set"/> </xsl:next-iteration> <xsl:on-completion> <highest-paid-employees> <xsl:value-of select="$highest/name"/> </highest-paid-employees> <lowest-paid-employees> <xsl:value-of select="$lowest/name"/> </lowest-paid-employees> </xsl:on-completion> </xsl:iterate> </xsl:stream>
If the input sequence is empty, this code outputs an empty
highest-paid-employees
element and an empty
lowest-paid-employees
element.
When streaming, some limited look-ahead is needed to determine
whether the item being processed is the last in a sequence. The
last
FO30
function cannot be used in guaranteed-streamable code. The
xsl:iterate
instruction
provides a solution to this problem.
Problem: render the last paragraph in a section in some special
way, for example by using bold face. (The actual rendition is
achieved by processing the paragraph with mode
last-para
.)
The solution uses xsl:iterate
together with
the copy-of
function to maintain a one-element lookahead by explicit
coding:
<xsl:template match="section" mode="streaming"> <xsl:iterate select="para"> <xsl:param name="prev" select="()" as="element(para)?"/> <xsl:if test="$prev"> <xsl:apply-templates select="$prev"/> </xsl:if> <xsl:next-iteration> <xsl:with-param name="prev" select="copy-of(.)"/> </xsl:next-iteration> <xsl:on-completion> <xsl:apply-templates select="$prev" mode="last-para"/> </xsl:on-completion> </xsl:iterate> </xsl:template>
There are two instructions in XSLT that support conditional
processing: xsl:if
and
xsl:choose
. The xsl:if
instruction provides simple
if-then conditionality; the xsl:choose
instruction supports
selection of one choice when there are several possibilities.
XSLT 3.0 also supports xsl:try
and xsl:catch
which define
conditional processing to handle dynamic errors.
xsl:if
<!-- Category: instruction -->
<xsl:if
test = expression >
<!-- Content: sequence-constructor
-->
</xsl:if>
The xsl:if
element has a
mandatory test
attribute, which specifies an expression.
The content is a sequence constructor.
The result of the xsl:if
instruction depends on the effective boolean
valueXP30 of the expression in the
test
attribute. The rules for determining the
effective boolean value of an expression are given in [XPath 3.0]: they are the same as the rules used
for XPath conditional expressions.
If the effective boolean value of the expression is true, then
the sequence constructor is evaluated
(see 5.8 Sequence
Constructors), and the resulting sequence is returned as
the result of the xsl:if
instruction; otherwise, the sequence constructor is not evaluated,
and the empty sequence is returned.
xsl:if
In the following example, the names in a group of names are formatted as a comma separated list:
<xsl:template match="namelist/name"> <xsl:apply-templates/> <xsl:if test="not(position()=last())">, </xsl:if> </xsl:template>
The following colors every other table row yellow:
<xsl:template match="item"> <tr> <xsl:if test="position() mod 2 = 0"> <xsl:attribute name="bgcolor">yellow</xsl:attribute> </xsl:if> <xsl:apply-templates/> </tr> </xsl:template>
xsl:choose
<!-- Category: instruction
-->
<xsl:choose>
<!-- Content: (xsl:when+, xsl:otherwise?) -->
</xsl:choose>
<xsl:when
test = expression >
<!-- Content: sequence-constructor
-->
</xsl:when>
<xsl:otherwise>
<!-- Content: sequence-constructor
-->
</xsl:otherwise>
The xsl:choose
element selects one among a number of possible alternatives. It
consists of a sequence of one or more xsl:when
elements followed by an
optional xsl:otherwise
element. Each
xsl:when
element has a
single attribute, test
, which specifies an expression.
The content of the xsl:when
and xsl:otherwise
elements is a
sequence constructor.
When an xsl:choose
element is processed, each of the xsl:when
elements is tested in
turn (that is, in the order that the elements appear in the
stylesheet), until one of the xsl:when
elements is satisfied. If
none of the xsl:when
elements is satisfied, then the xsl:otherwise
element is
considered, as described below.
An xsl:when
element is
satisfied if the effective boolean
valueXP30 of the expression
in its test
attribute is true
. The rules
for determining the effective boolean value of an expression are
given in [XPath 3.0]: they are the same as
the rules used for XPath conditional expressions.
The content of the first, and only the first, xsl:when
element that is satisfied
is evaluated, and the resulting sequence is returned as the result
of the xsl:choose
instruction. If no xsl:when
element is satisfied, the
content of the xsl:otherwise
element is
evaluated, and the resulting sequence is returned as the result of
the xsl:choose
instruction. If no xsl:when
element is satisfied, and
no xsl:otherwise
element is present, the result of the xsl:choose
instruction is an
empty sequence.
Only the sequence constructor of the selected xsl:when
or xsl:otherwise
instruction is
evaluated. The test
expressions for xsl:when
instructions after the
selected one are not evaluated.
xsl:choose
The following example enumerates items in an ordered list using arabic numerals, letters, or roman numerals depending on the depth to which the ordered lists are nested.
<xsl:template match="orderedlist/listitem"> <fo:list-item indent-start='2pi'> <fo:list-item-label> <xsl:variable name="level" select="count(ancestor::orderedlist) mod 3"/> <xsl:choose> <xsl:when test='$level=1'> <xsl:number format="i"/> </xsl:when> <xsl:when test='$level=2'> <xsl:number format="a"/> </xsl:when> <xsl:otherwise> <xsl:number format="1"/> </xsl:otherwise> </xsl:choose> <xsl:text>. </xsl:text> </fo:list-item-label> <fo:list-item-body> <xsl:apply-templates/> </fo:list-item-body> </fo:list-item> </xsl:template>
The xsl:try
instruction
can be used to trap dynamic errors occurring within the expression
it wraps; the recovery action if such errors occur is defined using
a child xsl:catch
element.
<!-- Category: instruction -->
<xsl:try
select? = expression >
<!-- Content: (sequence-constructor,
xsl:catch, (xsl:catch | xsl:fallback)*) -->
</xsl:try>
Note:
Because a sequence constructor may contain an xsl:fallback
element, the
effect of this content model is that an xsl:fallback
instruction may
appear as a child of xsl:try
in any position.
<xsl:catch
errors? = tokens
select? = expression >
<!-- Content: sequence-constructor
-->
</xsl:catch>
An xsl:try
instruction
evaluates either the expression contained in its
select
attribute, or its contained sequence constructor, and returns
the result of that evaluation if it succeeds without error. If a
dynamic error occurs during the evaluation,
the processor evaluates the first xsl:catch
child element
applicable to the error, and returns that result instead.
If the xsl:try
element
has a select
attribute, then it must have no children other than xsl:catch
and xsl:fallback
. That is, the
select
attribute and the contained sequence
constructor are mutually exclusive. If neither is present, the
result of the xsl:try
is an
empty sequence (no dynamic error can occur in this case).
[ERR XTSE3140] It is a static error if the
select
attribute of the xsl:try
element is present and the
element has children other than xsl:catch
and xsl:fallback
elements.
Any xsl:fallback
children of the xsl:try
element are ignored by an XSLT 3.0 processor, but can be used to
define the recovery action taken by an XSLT 1.0 or XSLT 2.0
processor operating with forwards
compatible behavior.
The xsl:catch
element
has an optional errors
attribute, which lists the
error conditions that the xsl:catch
element is designed to
intercept. The default value is errors="*"
, which
catches all errors. The value is a whitespace-separated list of
NameTestsXP30;
an xsl:catch
element
catches an error condition if this list includes a
NameTest
that matches the error code associated with
that error condition.
Note:
Error codes are QNames. Those defined in this specification and
in related specifications are all in the standard error namespace, and
may therefore be caught using an xsl:catch
element such as
<xsl:catch errors="err:FODC0001 err:FODC0005">
where the namespace prefix err
is bound to this
namespace. Errors defined by implementors, and errors raised by an
explicit call of the error
FO30
function or by use of the xsl:message
or xsl:assert
instruction,
may use error codes in other namespaces.
If more than one xsl:catch
element matches an
error, the error is processed using the first one that matches, in
document order. If no xsl:catch
matches the error, then
the error is not caught (that is, evaluation of the xsl:try
element fails with the
dynamic error).
An xsl:catch
element
may have either a select
attribute, or a contained
sequence constructor.
[ERR XTSE3150] It is a static error if the
select
attribute of the xsl:catch
element is present
unless the element has empty content.
The result of evaluating the xsl:catch
element is the result
of evaluating the XPath expression in its select
attribute or the result of evaluating the contained sequence
constructor; if neither is present, the result is an empty
sequence. This result is delivered as the result of the
xsl:try
instruction.
If a dynamic error occurs during the evaluation of xsl:catch
, it causes the
containing xsl:try
to fail
with this error. The error is not caught by other sibling xsl:catch
elements within the
same xsl:try
instruction,
but it may be caught by an xsl:try
instruction at an outer
level, or by an xsl:try
instruction nested within the xsl:catch
.
Within the select
expression, or within the
sequence constructor contained by the xsl:catch
element, a number of
variables are implicitly declared, giving information about the
error that occurred. These are lexically scoped to the
xsl:catch
element. These variables are all in the
standard error namespace, and
they are initialized as described in the following table:
| Variable | Type | Value |
|---|---|---|
| err:code | xs:QName | The error code |
| err:description | xs:string? | A description of the error condition;
an empty sequence if no description is available (for
example, if the error FO30
function was called with one argument). |
| err:value | item()* | Value associated with the error. For
an error raised by calling the error FO30
function, this is the value of the third argument (if supplied).
For an error raised by evaluating xsl:message with
terminate="yes" , or a failing xsl:assert , this is the
document node at the root of the tree containing the XML message
body. |
| err:module | xs:string? | The URI (or system ID) of the stylesheet module containing the instruction where the error occurred; an empty sequence if the information is not available. |
| err:line-number | xs:integer? | The line number within the stylesheet module of the instruction where the error occurred; an empty sequence if the information is not available. The value may be approximate. |
| err:column-number | xs:integer? | The column number within the stylesheet module of the instruction where the error occurred; an empty sequence if the information is not available. The value may be approximate. |
Variables declared within the sequence constructor of the
xsl:try
element (and not
within an xsl:catch
) are
not visible within the xsl:catch
element.
Note:
Within an xsl:catch
it
is possible to re-throw the error using the function call
error($err:code, $err:description, $err:value)
.
The following additional rules apply to the catching of errors:
All dynamic errors occurring during the evaluation of the
xsl:try
sequence
constructor or select
expression are caught (provided
they match one of the xsl:catch
elements).
This includes errors occurring in functions or templates invoked
in the course of this evaluation, unless already caught by a nested
xsl:try
.
It also includes errors caused by calling the error
FO30
function, or the xsl:message
instruction with
terminate="yes"
, or the xsl:assert
instruction.
It does not include errors that occur while evaluating
references to variables whose declaration and initialization is
outside the xsl:try
.
The existence of an xsl:try
instruction does not affect
the obligation of the processor to signal certain errors as static
errors, or its right to choose whether to signal some errors (such
as type
errors) statically or dynamically. Static errors are never
caught.
Some fatal errors arising in the processing environment, such as
running out of memory, may cause termination of the transformation
despite the presence of an xsl:try
instruction. This is
implementation-dependent.
If the sequence constructor or select
expression of
the xsl:try
causes
execution of xsl:result-document
,
xsl:message
, or
xsl:assert
instructions and fails with a dynamic error that is caught, it is
implementation-dependent whether these instructions have any
externally visible effect. The processor is not
required to roll back any changes made by these
instructions. The same applies to any side effects caused by
extension functions or extension instructions.
A serialization error that occurs during the serialization of a
final result tree produced using
xsl:result-document
is
treated as a dynamic error in the evaluation of the xsl:result-document
instruction, and may be caught by a containing xsl:try
instruction. A
serialization error that occurs while serializing the implicit
final result tree returned by the
initial template is treated as occurring
after the transformation has finished, and cannot be caught.
A validation error is treated as occurring in the instruction
that requested validation. For example, if the stylesheet is
producing XHTML output and requests validation of the entire result
document by means of the attribute validation="strict"
on the instruction that creates the outermost html
element, then a validation failure can be caught only at that
level. Although the validation error might be detected, for
example, while writing a p
element at a location where
no p
element is allowed, it is not treated as an error
in the instruction that writes the p
element and
cannot be caught at that level.
A type error may be caught if the processor raises it dynamically; this does not affect the processor's right to raise the error statically if it chooses.
The following rules are provided to define which expression is considered to fail when a type error occurs, and therefore where the error can be caught. The general principle is that where the semantics of a construct C place requirements on the type of some subexpression, a type error is an error in the evaluation of C, not in the evaluation of the subexpression.
For example, consider the following construct:
<xsl:variable name="v" as="xs:integer"> <xsl:sequence select="$foo"/> </xsl:variable>
The expected type of the result of the sequence constructor is
xs:integer
; if the value of variable $foo
turns out to be a string, then a type error will occur. It is not
possible to catch this by writing:
<xsl:variable name="v" as="xs:integer"> <xsl:try> <xsl:sequence select="$foo"/> <xsl:catch>...</xsl:catch> </xsl:try> </xsl:variable>
This fails to catch the error because the xsl:sequence
instruction is
deemed to evaluate successfully; the failure only occurs when the
result of this instruction is bound to the variable.
A similar rule applies to functions: if the body of a function computes a result which does not conform to the required type of the function result, it is not possible to catch this error within the function body itself; it can only be caught by the caller of the function. Similarly, if an expression used to compute an argument to a function returns a value of the wrong type for the function signature, this is not considered an error in this expression, but an error in evaluating the function call as a whole.
A consequence of these rules is that when a type error occurs while initializing a global variable (because the initializer returns a value of the wrong type, given the declared type of the variable), then this error cannot be caught.
Note:
Because processors are permitted to report type errors during
static analysis, it is unwise to attempt to recover from type
errors dynamically. The best strategy is generally to prevent their
occurrence. For example, rather than writing $p + 1
where $p
is a parameter of unknown type, and then
catching the type error that occurs if $p
is not
numeric, it is better first to test whether $p
is
numeric, perhaps by means of an expression such as $p
instance of my:numeric
, where my:numeric
is a
union type with xs:double
, xs:float
, and
xs:decimal
as its member types.
The fact that the application tries to catch errors does not
prevent the processor from organizing the evaluation in such a way
as to prevent errors occurring. For example exists(//a[10 div
. gt 5])
may still do an "early exit", rather than examining
every item in the sequence just to see if it triggers a
divide-by-zero error.
Except as specified above, the optimizer must not rearrange the evaluation (at compile time or at run time) so that expressions written to be subject to the try/catch are evaluated outside its scope, or expressions written to be external to the try/catch are evaluated within its scope. This does not prevent expressions being rearranged, but any expression that is so rearranged must carry its try/catch context with it.
Note:
If an error occurs while evaluating an instruction within
xsl:try
, then no
instruction within the xsl:try
has any effect on the
result returned by the xsl:try
instruction. This means
that if a processor is streaming the output to a serializer, it
needs to adopt a strategy such as buffering the output in memory so
that nothing is written until successful completion of the xsl:try
instruction, or
checkpointing the output so it can be rolled back when an error
occurs.
Note:
Use of try/catch may affect the ability of a processor to
perform streamed evaluation of a stylesheet. If the sequence
constructor contained within xsl:try
creates a sequence of ten
elements, and these form part of a final result tree, then if a
failure occurs while writing the tenth element, the work of
creating the previous nine must be "undone". In effect this means
that either the processor must delay sending the new elements to
the serializer until it is assured of success, or the serializer
must provide a mechanism to roll back elements already written.
The following example divides an employee's salary by the number of years they have served, catching the divide-by-zero error if the latter is zero.
<xsl:try select="salary div length-of-service"> <xsl:catch errors="err:FAOR0001" select="()"/> </xsl:try>
The following example generates a result tree and performs schema validation, outputting a warning message and serializing the invalid tree if validation fails.
<xsl:result-document href="out.xml"> <xsl:variable name="result"> <xsl:call-template name="construct-output"/> </xsl:variable> <xsl:try> <xsl:copy-of select="$result" validation="strict"/> <xsl:catch> <xsl:message>Warning: validation of result document failed: Error code: <xsl:value-of select="$err:code"/> Reason: <xsl:value-of select="$err:description"/> </xsl:message> <xsl:sequence select="$result"/> </xsl:catch> </xsl:try> </xsl:result-document>
The reason that the result tree is constructed in a variable in
this example is so that the unvalidated tree is available to be
used within the xsl:catch
element. An alternative approach would be to repeat the logic for
constructing the tree:
<xsl:try> <xsl:result-document href="out.xml" validation="strict"> <xsl:call-template name="construct-output"/> </xsl:result-document> <xsl:catch> <xsl:message>Warning: validation of result document failed: Error code: <xsl:value-of select="$err:code"/> Reason: <xsl:value-of select="$err:description"/> </xsl:message> <xsl:call-template name="construct-output"/> </xsl:catch> </xsl:try>
[Definition: The two elements xsl:variable
and xsl:param
are referred to as
variable-binding elements ].
[Definition: The xsl:variable
element declares
a variable, which may be a global variable or a
local variable.]
[Definition: The xsl:param
element declares a
parameter, which may be a stylesheet
parameter, a template parameter, a function parameter, or an
xsl:iterate
parameter. A parameter is a variable with the additional
property that its value can be set by the caller.]
[Definition: A variable is a binding between a name and a value. The value of a variable is any sequence (of nodes, atomic values, and/or function items), as defined in [Data Model].]
<!-- Category: declaration
-->
<!-- Category: instruction -->
<xsl:variable
name = eqname
select? = expression
as? = sequence-type
static? = "yes" | "no"
visibility? = "public" | "private" | "final" |
"abstract" >
<!-- Content: sequence-constructor
-->
</xsl:variable>
The xsl:variable
element has a required name
attribute, which specifies the name of the variable. The value of
the name
attribute is an EQName, which is
expanded as described in 5.1 Qualified
Names.
The xsl:variable
element has an optional as
attribute, which specifies
the required type of the variable. The value of
the as
attribute is a SequenceTypeXP30,
as defined in [XPath 3.0].
[Definition: The value of the variable is computed using
the expression given in the select
attribute or the contained sequence constructor,
as described in 9.3 Values of
Variables and Parameters. This value is referred to as the
supplied value of the variable.] If the xsl:variable
element has a
select
attribute, then the sequence constructor
must be empty.
If the as
attribute is specified, then the
supplied value of the variable is
converted to the required type, using the function conversion rules.
[ERR XTTE0570] It is a type error if the supplied value of a variable cannot be converted to the required type.
If the as
attribute is omitted, the supplied
value of the variable is used directly, and no conversion takes
place.
For the effect of the static
attribute, see
9.6 Static Variables and
Parameters.
The visibility
attribute must
not be specified for a local variable: that is, it is
allowed only when the parent element is
xsl:stylesheet
, xsl:transform
, or
xsl:override
.
If the visibility
attribute is present with the
value abstract
then the select
attribute
must be absent and the contained
sequence constructor must be empty. In this situation there is no
supplied value, and therefore the
constraint that the supplied value is consistent with the required
type does not apply.
<!-- Category: declaration
-->
<xsl:param
name = eqname
select? = expression
as? = sequence-type
required? = "yes" | "no"
tunnel? = "yes" | "no"
static? = "yes" | "no"
visibility? = "public" | "private" | "final" |
"abstract" >
<!-- Content: sequence-constructor
-->
</xsl:param>
The xsl:param
element
may be used:
as a child of xsl:stylesheet
, to define a
parameter to the transformation
as a child of xsl:template
to define a
parameter to a template, which may be supplied when the template is
invoked using xsl:call-template
,
xsl:apply-templates
,
xsl:apply-imports
or xsl:next-match
;
as a child of xsl:function
to define a
parameter to a stylesheet function, which may be supplied when the
function is called from an XPath expression
as a child of xsl:iterate
to define a
parameter that can vary from one iteration to the next.
The xsl:param
element
has a required name
attribute, which specifies the name of the parameter. The value of
the name
attribute is an EQName, which is
expanded as described in 5.1 Qualified
Names.
[ERR XTSE0580] It is a static error if the
values of the name
attribute of two sibling
xsl:param
elements
represent the same expanded QName.
Note:
For rules concerning stylesheet parameters, see 9.5 Global Variables and Parameters. Local variables may shadow template parameters and function parameters: see 9.9 Scope of Variables.
The supplied value of the parameter is the
value supplied by the caller. If no value was supplied by the
caller, and if the parameter is not mandatory, then the supplied
value is computed using the expression given in the
select
attribute or the contained sequence constructor, as described
in 9.3 Values of Variables and
Parameters. If the xsl:param
element has a
select
attribute, then the sequence constructor
must be empty.
Note:
This specification does not dictate whether and when the default
value of a parameter is evaluated. For example, if the default is
specified as <xsl:param
name="p"><foo/></xsl:param>
, then it is not
specified whether a distinct foo
element node will be
created on each invocation of the template, or whether the same
foo
element node will be used for each invocation.
However, it is permissible for the default value to depend on the
values of other parameters, or on the evaluation context, in which
case the default must effectively be evaluated on each
invocation.
The xsl:param
element
has an optional as
attribute, which specifies the
required type of the parameter. The value
of the as
attribute is a SequenceTypeXP30,
as defined in [XPath 3.0].
If the as
attribute is specified, then the
supplied value of the parameter is
converted to the required type, using the function conversion rules.
[ERR XTTE0590] It is a type error if the conversion of the supplied value of a parameter to its required type fails.
If the as
attribute is omitted, the supplied
value of the parameter is used directly, and no conversion
takes place.
The optional required
attribute may be used to
indicate that a parameter is mandatory. This attribute may be
specified for stylesheet parameters and for
template parameters; it must not be specified for function parameters, which are always
mandatory, or for parameters to xsl:iterate
, which are always
initialized to a default value. A parameter is mandatory if
it is a function parameter or if the
required
attribute is present and has the value
yes
. Otherwise, the parameter is optional. If the
parameter is mandatory, then the xsl:param
element must be empty and must not
have a select
attribute.
[ERR XTTE0600] If a default value is given
explicitly, that is, if there is either a select
attribute or a non-empty sequence constructor,
then it is a type error if the default value cannot be
converted to the required type, using the function conversion rules.
If a stylesheet parameter specifies required="yes"
and does not specify static="yes"
, then its visibility
must be public
, final
, or
abstract
. The default visibility of such a parameter
is public
.
[ERR XTSE3370] It is a static error if the the
visibility
attribute of a stylesheet parameter that
specifies required="yes"
and does not specify
static="yes"
is present with a value other than
public
, final
, or abstract
,
or if an xsl:expose
or
xsl:accept
declaration
attempts to modify the visibility of such a component to a value
other than public
, final
, or
abstract
.
Note:
This rule has the effect that after combining all the packages making up a stylesheet, the non-static stylesheet parameters whose values are required necessarily have distinct names, which simplifies the design of APIs.
If an optional parameter has no select
attribute
and has an empty sequence constructor, and if
there is no as
attribute, then the default value of
the parameter is a zero length string.
[ERR XTDE0610] If an optional parameter has no
select
attribute and has an empty sequence constructor, and if there
is an as
attribute, then the default value of the
parameter is an empty sequence. If the empty sequence is not a
valid instance of the required type defined in the as
attribute, then the parameter is treated as a required parameter,
which means that it is a dynamic error if the caller supplies
no value for the parameter.
For the effect of the static
attribute, see
9.6 Static Variables and
Parameters.
The visibility
attribute must
not be specified for a local parameter: that is, it is
allowed only when the parent element is
xsl:stylesheet
, xsl:transform
, or
xsl:override
.
If the visibility
attribute is present with the
value abstract
then the select
attribute
must be absent and the contained
sequence constructor must be empty. In this situation there is no
supplied value, and therefore the
constraint that the supplied value is consistent with the required
type does not apply.
Note:
The effect of these rules is that specifying <xsl:param
name="p" as="xs:date" select="2"/>
is an error, but if
the default value of the parameter is never used, then the
processor has discretion whether or not to report the error. By
contrast, <xsl:param name="p" as="xs:date"/>
is
treated as if required="yes"
had been specified: the
empty sequence is not a valid instance of xs:date
, so
in effect there is no default value and the parameter is therefore
treated as being mandatory.
The optional tunnel
attribute may be used to
indicate that a parameter is a tunnel parameter. The
default is no
; the value yes
may be
specified only for template parameters. Tunnel
parameters are described in 10.1.2
Tunnel Parameters
A variable-binding element may specify the supplied value of a variable or the default value of a parameter in four different ways.
If the variable-binding element has a
select
attribute, then the value of the attribute
must be an expression and the supplied
value of the variable is the value that results from evaluating
the expression. In this case, the content of the variable-binding
element must be empty.
If the variable-binding element has
empty content and has neither a select
attribute nor
an as
attribute, then the supplied value of the
variable is a zero-length string. Thus
<xsl:variable name="x"/>
is equivalent to
<xsl:variable name="x" select="''"/>
If a variable-binding element has no
select
attribute and has non-empty content (that is,
the variable-binding element has one or more child nodes), and has
no as
attribute, then the content of the
variable-binding element specifies the supplied value. The
content of the variable-binding element is a sequence constructor; a new document
is constructed with a document node having as its children the
sequence of nodes that results from evaluating the sequence
constructor and then applying the rules given in 5.8.1 Constructing Complex
Content. The value of the variable is then a singleton
sequence containing this document node. For further information,
see 9.4 Creating Implicit Document
Nodes.
If a variable-binding element has an
as
attribute but no select
attribute,
then the supplied value is the sequence that
results from evaluating the (possibly empty) sequence constructor contained
within the variable-binding element (see 5.8 Sequence Constructors).
These combinations are summarized in the table below.
| select attribute | as attribute | content | Effect |
|---|---|---|---|
| present | absent | empty | Value is obtained by evaluating the
select attribute |
| present | present | empty | Value is obtained by evaluating the
select attribute, adjusted to the type required by the
as attribute |
| present | absent | present | Static error |
| present | present | present | Static error |
| absent | absent | empty | Value is a zero-length string |
| absent | present | empty | Value is an empty sequence, provided
the as attribute permits an empty sequence |
| absent | absent | present | Value is a document node whose content is obtained by evaluating the sequence constructor |
| absent | present | present | Value is obtained by evaluating the
sequence constructor, adjusted to the type required by the
as attribute |
[ERR XTSE0620] It is a static error if a
variable-binding element has a
select
attribute and has non-empty content.
The value of the following variable is the sequence of integers (1, 2, 3):
<xsl:variable name="i" as="xs:integer*" select="1 to 3"/>
The value of the following variable is an integer, assuming that
the attribute @size
exists, and is annotated either as
an integer, or as xs:untypedAtomic
:
<xsl:variable name="i" as="xs:integer" select="@size"/>
The value of the following variable is a zero-length string:
<xsl:variable name="z"/>
The value of the following variable is a document node containing an empty element as a child:
<xsl:variable name="doc"><c/></xsl:variable>
The value of the following variable is a sequence of integers (2, 4, 6):
<xsl:variable name="seq" as="xs:integer*"> <xsl:for-each select="1 to 3"> <xsl:sequence select=".*2"/> </xsl:for-each> </xsl:variable>
The value of the following variable is a sequence of parentless attribute nodes:
<xsl:variable name="attset" as="attribute()+"> <xsl:attribute name="x">2</xsl:attribute> <xsl:attribute name="y">3</xsl:attribute> <xsl:attribute name="z">4</xsl:attribute> </xsl:variable>
The value of the following variable is an empty sequence:
<xsl:variable name="empty" as="empty-sequence()"/>
The actual value of the variable depends on the supplied
value, as described above, and the required type, which is
determined by the value of the as
attribute.
When a variable is used to select nodes by position, be careful not to do:
<xsl:variable name="n">2</xsl:variable> ... <xsl:value-of select="td[$n]"/>
This will output the values of all the td
elements,
space-separated (or with XSLT 1.0 behavior,
the value of the first td
element), because the
variable n
will be bound to a node, not a number.
Instead, do one of the following:
<xsl:variable name="n" select="2"/> ... <xsl:value-of select="td[$n]"/>
or
<xsl:variable name="n">2</xsl:variable> ... <xsl:value-of select="td[position()=$n]"/>
or
<xsl:variable name="n" as="xs:integer">2</xsl:variable> ... <xsl:value-of select="td[$n]"/>
A document node is created implicitly when evaluating an
xsl:variable
, xsl:param
, or xsl:with-param
element that
has non-empty content and that has no as
attribute.
The value of the variable is a single node, the document node of
a temporary tree. The content of the
document node is formed from the result of evaluating the sequence constructor contained
within the variable-binding element, as described in 5.8.1 Constructing Complex
Content.
Note:
The construct:
<xsl:variable name="tree"> <a/> </xsl:variable>
can be regarded as a shorthand for:
<xsl:variable name="tree" as="document-node()"> <xsl:document validation="preserve"> <a/> </xsl:document> </xsl:variable>
The base URI of the document node is taken from the base URI of the variable binding element in the stylesheet. (See Section 5.2 base-uri Accessor DM30 in [Data Model])
No document-level validation takes place (which means, for example, that there is no checking that ID values are unique). However, type annotations on nodes within the new tree are copied unchanged.
Note:
The base URI of other nodes in the tree is determined by the
rules for constructing complex content. The effect of these rules
is that the base URI of a node in the temporary tree is determined
as if all the nodes in the temporary tree came from a single entity
whose URI was the base URI of the variable-binding element. Thus,
the base URI of the document node will be equal to the base URI of
the variable-binding element, while an xml:base
attribute within the temporary tree will change the base URI for
its parent element and that element's descendants, just as it would
within a document constructed by parsing.
The document-uri
and unparsed-entities
properties of the new document node are set to empty.
A temporary tree is available for processing
in exactly the same way as any source document. For example, its
nodes are accessible using path expressions, and they can be
processed using instructions such as xsl:apply-templates
and
xsl:for-each
. Also,
the key
and id
FO30
functions can be used to find nodes within a temporary tree,
by supplying the document node at the root of the tree as an
argument to the function or by making it the context
node.
For example, the following stylesheet uses a temporary tree as
the intermediate result of a two-phase transformation, using
different modes
for the two phases (see 6.6 Modes).
Typically, the template rules in module phase1.xsl
will be declared with mode="phase1"
, while those in
module phase2.xsl
will be declared with
mode="phase2"
:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:import href="phase1.xsl"/> <xsl:import href="phase2.xsl"/> <xsl:variable name="intermediate"> <xsl:apply-templates select="/" mode="phase1"/> </xsl:variable> <xsl:template match="/"> <xsl:apply-templates select="$intermediate" mode="phase2"/> </xsl:template> </xsl:stylesheet>
Note:
The algorithm for matching nodes against template rules is exactly the same regardless which tree the nodes come from. If different template rules are to be used when processing different trees, then unless nodes from different trees can be distinguished by means of patterns, it is a good idea to use modes to ensure that each tree is processed using the appropriate set of template rules.
Both xsl:variable
and xsl:param
are allowed
as declaration elements: that is, they may
appear as children of the xsl:stylesheet
element.
[Definition: A top-level variable-binding element declares a global variable that is visible everywhere (except within its own declaration, and where it is shadowed by another binding).]
[Definition: A top-level xsl:param
element declares a
stylesheet parameter. A stylesheet parameter is a global
variable with the additional property that its value can be
supplied by the caller when a transformation is
initiated.] As described in
9.2 Parameters, a stylesheet
parameter may be declared as being mandatory, or may have a default
value specified for use when no value is supplied by the caller.
The mechanism by which the caller supplies a value for a stylesheet
parameter is implementation-defined. An
XSLT processor must
provide such a mechanism.
It is an error if no value is supplied for a mandatory stylesheet parameter [see ERR XTDE0050].
If a stylesheet contains more than one binding for a global variable of a particular name, then the binding with the highest import precedence is used.
[ERR XTSE0630] It is a static error if a stylesheet contains more than one non-hidden binding of a global variable with the same name and same import precedence, unless it also contains another binding with the same name and higher import precedence.
For a global variable or the default value of a stylesheet parameter, the expression or sequence constructor specifying the variable value is evaluated with a singleton focus based on the root node of the tree containing the initial context item. An XPath error will be reported if the evaluation of a global variable or parameter references the context item, context position, or context size when no initial context item is supplied. The values of other components of the dynamic context are the initial values as defined in 5.4.3 Initializing the Dynamic Context and 5.4.4 Additional Dynamic Context Components used by XSLT.
The following example declares a global parameter
para-font-size
, which is referenced in an attribute value template.
<xsl:param name="para-font-size" as="xs:string">12pt</xsl:param> <xsl:template match="para"> <fo:block font-size="{$para-font-size}"> <xsl:apply-templates/> </fo:block> </xsl:template>
The implementation must provide a mechanism allowing the user to
supply a value for the parameter para-font-size
when
invoking the stylesheet; the value 12pt
acts as a
default.
Static variables and parameters are global variables and can be
used in the same way as other global variables. In addition, they
can be used in [xsl:]use-when
expressions.
[Definition: A top-level variable-binding element having
the attribute static="yes"
declares a static
variable: that is, a global variable whose value is known
during static analysis of the stylesheet.]
[Definition: A static variable declared using an
xsl:param
element is
referred to as a static parameter.]
The static
attribute must
not be present on an xsl:variable
or xsl:param
element unless it is a
top-level element.
When the static
attribute is present with the value
yes
, the visibility
attribute
must not have a value other than
private
or final
.
Note:
This rule prevents static variables being overridden in another
package. Since the values of such variables may be used at compile
time (for example, during processing of [xsl:]use-when
expressions), the rule is necessary to ensure that packages can be
independently compiled.
Declaring a static variable or parameter with
visibility="final"
allows its value to be used in
ordinary (non-static) expressions in a using package, but use in
static expressions is possible only within the same package.
When the attribute static="yes"
is specified, the
xsl:variable
or
xsl:param
element
must have empty content. In the case of
xsl:variable
the
select
attribute must be present to define the value
of the variable.
If the select
attribute is present, then it is
evaluated using the rules for static expressions.
[Definition: A static expression is an XPath expression whose value must be computed during static analysis of the stylesheet.]
Static expressions appear in two contexts:
In [xsl:]use-when
attributes (see 3.14 Conditional Element
Inclusion)
In the select
attribute of static
variable declarations (xsl:variable
or xsl:param
with
static="yes"
).
There are no syntactic constraints on the XPath expression that can be used as a static expression. However, there are severe constraints on the information provided in its evaluation context. These constraints are designed to ensure that the expression can be evaluated at the earliest possible stage of stylesheet processing, without any dependency on information contained in the stylesheet itself or in any source document.
Specifically, the components of the static and dynamic context are defined by the following two tables:
| Component | Value |
|---|---|
| XPath 1.0 compatibility mode | false |
| Statically known namespaces | determined by the in-scope namespaces for the containing element in the stylesheet |
| Default element/type namespace | determined by the
xpath-default-namespace attribute if present (see
5.2 Unprefixed Lexical QNames in
Expressions and Patterns); otherwise the null
namespace |
| Default function namespace | The standard function namespace |
| In-scope schema types | The type definitions that would be
available in the absence of any xsl:import-schema
declaration |
| In-scope element declarations | None |
| In-scope attribute declarations | None |
| In-scope variables | The static variables visible
within the containing package whose declarations occur prior to the
element containing the static expression in stylesheet tree order.
Stylesheet tree order is the order that results when all xsl:import and xsl:include declarations are
replaced by the declarations in the imported or included stylesheet
module. A static variable is not in scope within its own
declaration, and it is in scope only within its declaring
package, not in any using packages. If two static variables
satisfying this rule have the same name and are both in scope, the
one that has highest import precedence is used (it is a
consequence of rules defined elsewhere that there cannot be more
than one declaration with highest import precedence). Note that the
declaration with highest import precedence is not necessarily the
one that appears last in stylesheet tree order; note also that
because forwards references are not allowed, the declaration that
is used will not necessarily be the one with highest import
precedence in the stylesheet as a whole. |
| Context item static type | Absent |
| Statically known function signatures | The core functions defined in
[Functions and Operators],
together with the functions element-available ,
function-available ,
type-available , and
system-property
defined in this specification, plus the set of extension functions
that are present in the static context of every XPath expression
(other than a use-when expression) within the content of the
element that is the parent of the use-when attribute.
Note that stylesheet functions are not
included in the context, which means that the function function-available will
return false in respect of such functions. The effect
of this rule is to ensure that function-available
returns true in respect of functions that can be called within the
scope of the use-when attribute. It also has the
effect that these extension functions will be recognized within the
use-when attribute itself; however, the fact that a
function is available in this sense gives no guarantee that a call
on the function will succeed. |
| Statically known collations | Implementation-defined |
| Default collation | The Unicode Codepoint Collation |
| Static Base URI | The base URI of the containing element in the stylesheet document (see Section 5.2 base-uri Accessor DM30) |
| Statically known documents | Implementation-defined |
| Statically known collections | Implementation-defined |
| Statically known default collection type | Implementation-defined |
| Statically known decimal formats | A single unnamed decimal
format equivalent to the decimal format that is created by an
xsl:decimal-format
declaration with no attributes. |
| Component | Value |
|---|---|
| Context item, position, and size | Absent |
| Variable values | A value for every variable present in the in-scope variables. For static parameters where an external value is supplied: the externally-supplied value of the parameter. In all other cases: the value of the variable as defined in 9.3 Values of Variables and Parameters. |
| Named functions | The function implementation corresponding to each function signature in the statically known function signatures |
| Current dateTime | Implementation-defined |
| Implicit timezone | Implementation-defined |
| Default language | Implementation-defined |
| Default calendar | Implementation-defined |
| Default place | Implementation-defined |
| Available documents | Implementation-defined |
| Available collections | Implementation-defined |
| Default collection | Implementation-defined |
| Environment variables | Implementation-defined |
Within a stylesheet module, all static
expressions are evaluated in a single execution
scopeFO30. This need not be the same
execution scope as that used for static expressions in other
stylesheet modules, or as that used when evaluating XPath
expressions appearing elsewhere in the stylesheet module. This
means that a function such as current-date
FO30
will return the same result when called in different
[xsl:]use-when
expressions within the same stylesheet
module, but will not necessarily return the same result as the same
call in an [xsl:]use-when
expression within a
different stylesheet module, or as a call on the same function
executed during the transformation proper.
[Definition: As well as being allowed as a declaration, the xsl:variable
element is also
allowed in sequence constructors. Such a
variable is known as a local variable.]
An xsl:param
element
may also be used to create a variable binding with local scope:
[Definition: An xsl:param
element may appear as a
child of an xsl:template
element, before
any non-xsl:param
children of that element. Such a parameter is known as a
template parameter. A template parameter is a local
variable with the additional property that its value can be set
when the template is called, using any of the instructions xsl:call-template
,
xsl:apply-templates
,
xsl:apply-imports
, or
xsl:next-match
.]
[Definition: An xsl:param
element may appear as a
child of an xsl:function
element, before
any non-xsl:param
children of that element. Such a parameter is known as a
function parameter. A function parameter is a local
variable with the additional property that its value can be set
when the function is called, using a function call in an XPath
expression.]
An xsl:param
element
may appear as a child of an xsl:iterate
instruction, before
any non-xsl:param
children of that element. This defines a parameter whose value may
be initialized on entry to the iteration, and which may be varied
each time round the iteration by use of an xsl:with-param
element in
the xsl:next-iteration
instruction.
The result of evaluating a local xsl:variable
or xsl:param
element (that is, the
contribution it makes to the result of the sequence constructor it is part of)
is an empty sequence.
For any variable-binding element, there is a region (more specifically, a set of nodes) of the stylesheet within which the binding is visible. The set of variable bindings in scope for an XPath expression consists of those bindings that are visible at the point in the stylesheet where the expression occurs.
A global variable binding element is
visible everywhere in the stylesheet (including other stylesheet modules) except within the
xsl:variable
or
xsl:param
element itself
and any region where it is shadowed by another variable binding.
A local variable binding element is visible for all following siblings and their descendants, with the following exceptions:
It is not visible in any region where it is shadowed by another variable binding.
It is not visible within the subtree rooted at an xsl:fallback
instruction that
is a sibling of the variable binding element.
It is not visible within the subtree rooted at an xsl:catch
instruction that is a
sibling of the variable binding element.
The binding is not visible for the xsl:variable
or xsl:param
element itself.
If a binding is visible for an element then it is visible for every attribute of that element and for every text node child of that element.
[Definition: A binding
shadows another binding if the binding occurs at a point
where the other binding is visible, and the bindings have the same
name. ] It is not an error if a
binding established by a local xsl:variable
or xsl:param
shadows a global binding. In
this case, the global binding will not be visible in the region of
the stylesheet where it is shadowed by the other
binding.
The following is allowed:
<xsl:param name="x" select="1"/> <xsl:template name="foo"> <xsl:variable name="x" select="2"/> </xsl:template>
It is also not an error if a binding established by a local
xsl:variable
element
shadows a
binding established by another local xsl:variable
or xsl:param
.
The following is not an error, but the effect is probably not
what was intended. The template outputs <x
value="1"/>
, because the declaration of the inner
variable named $x
has no effect on the value of the
outer variable named $x
.
<xsl:variable name="x" select="1"/> <xsl:template name="foo"> <xsl:for-each select="1 to 5"> <xsl:variable name="x" select="$x+1"/> </xsl:for-each> <x value="{$x}"/> </xsl:template>
Note:
Once a variable has been given a value, the value cannot subsequently be changed. XSLT does not provide an equivalent to the assignment operator available in many procedural programming languages.
This is because an assignment operator would make it harder to create an implementation that processes a document other than in a batch-like way, starting at the beginning and continuing through to the end.
As well as global variables and local variables, an XPath expression may also declare range variables for use locally within an expression. For details, see [XPath 3.0].
Where a reference to a variable occurs in an XPath expression, it is resolved first by reference to range variables that are in scope, then by reference to local variables and parameters, and finally by reference to global variables and parameters. A range variable may shadow a local variable or a global variable. XPath also allows a range variable to shadow another range variable.
<xsl:with-param
name = eqname
select? = expression
as? = sequence-type
tunnel? = "yes" | "no" >
<!-- Content: sequence-constructor
-->
</xsl:with-param>
Parameters are passed to templates using the xsl:with-param
element. The
required name
attribute
specifies the name of the template parameter (the
variable the value of whose binding is to be replaced). The value
of the name
attribute is an EQName, which is
expanded as described in 5.1 Qualified
Names.
The xsl:with-param
element is
also used when passing parameters to an iteration of the xsl:iterate
instruction, or to
a dynamic invocation of an XPath expression using xsl:evaluate
. In
consequence, xsl:with-param
may appear
within xsl:apply-templates
,
xsl:apply-imports
,
xsl:call-template
,
xsl:evaluate
,
xsl:next-iteration
,
and xsl:next-match
.
(Arguments to stylesheet functions, however, are
supplied as part of an XPath function call: see 10.3 Stylesheet Functions.)
[ERR XTSE0670] It is a static error if two or
more sibling xsl:with-param
elements have
name
attributes that represent the same expanded
QName.
The value of the parameter is specified in the same way as for
xsl:variable
and
xsl:param
(see 9.3 Values of Variables and
Parameters), taking account of the values of the
select
and as
attributes and the content
of the xsl:with-param
element, if
any.
Note:
It is possible to have an as
attribute on the
xsl:with-param
element that differs from the as
attribute on the
corresponding xsl:param
element.
In this situation, the supplied value of the parameter will
first be processed according to the rules of the as
attribute on the xsl:with-param
element, and
the resulting value will then be further processed according to the
rules of the as
attribute on the xsl:param
element.
For example, suppose the supplied value is a node with type
annotation xs:untypedAtomic
, and the xsl:with-param
element
specifies as="xs:integer"
, while the xsl:param
element specifies
as="xs:double"
. Then the node will first be atomized
and the resulting untyped atomic value will be cast to
xs:integer
. If this succeeds, the
xs:integer
will then be promoted to an
xs:double
.
The focus
used for computing the value specified by the xsl:with-param
element is
the same as that used for its parent instruction.
The optional tunnel
attribute may be used to
indicate that a parameter is a tunnel parameter. The
default is no
. Tunnel parameters are described in
10.1.2 Tunnel Parameters. They
are used only when passing parameters to templates: for an xsl:with-param
element that
is a child of xsl:evaluate
or xsl:next-iteration
the
tunnel
attribute must either
be omitted or take the value no
.
In other cases it is a dynamic error if the template that is
invoked declares a template parameter with
required="yes"
and no value for this parameter is
supplied by the calling instruction. [see
ERR XTDE0700]
[Definition: A circularity is said to exist if a construct such as a global variable, an attribute set, or a key, is defined in terms of itself. For example, if the expression or sequence constructor specifying the value of a global variable X references a global variable Y, then the value for Y must be computed before the value of X. A circularity exists if it is impossible to do this for all global variable definitions.]
The following two declarations create a circularity:
<xsl:variable name="x" select="$y+1"/> <xsl:variable name="y" select="$x+1"/>
The definition of a global variable can be circular even if no
other variable is involved. For example the following two
declarations (see 10.3
Stylesheet Functions for an explanation of the xsl:function
element) also
create a circularity:
<xsl:variable name="x" select="my:f()"/> <xsl:function name="my:f"> <xsl:sequence select="$x"/> </xsl:function>
The definition of a variable is also circular if the evaluation
of the variable invokes an xsl:apply-templates
instruction and the variable is referenced in the pattern used in
the match
attribute of any template rule in the
stylesheet. For example the following
definition is circular:
<xsl:variable name="x"> <xsl:apply-templates select="//param[1]"/> </xsl:variable> <xsl:template match="param[$x]">1</xsl:template>
Similarly, a variable definition is circular if it causes a call
on the key
function, and the
definition of that key
refers to that variable in its match
or
use
attributes. So the following definition is
circular:
<xsl:variable name="x" select="my:f(10)"/> <xsl:function name="my:f"> <xsl:param name="arg1"/> <xsl:sequence select="key('k', $arg1)"/> </xsl:function> <xsl:key name="k" match="item[@code=$x]" use="@desc"/>
[ERR XTDE0640] In general, a circularity in a stylesheet is a dynamic error. However, as with all other dynamic errors, an implementation will signal the error only if it actually executes the instructions and expressions that participate in the circularity. Because different implementations may optimize the execution of a stylesheet in different ways, it is implementation-dependent whether a particular circularity will actually be signaled.
For example, in the following declarations, the function
declares a local variable $b
, but it returns a result
that does not require the variable to be evaluated. It is implementation-dependent whether
the value is actually evaluated, and it is therefore
implementation-dependent whether the circularity is signaled as an
error:
<xsl:variable name="x" select="my:f(1)"/> <xsl:function name="my:f"> <xsl:param name="a"/> <xsl:variable name="b" select="$x"/> <xsl:sequence select="$a + 2"/> </xsl:function>
Circularities usually involve global variables or parameters,
but they can also exist between key definitions (see 20.2
Keys), between named attribute sets (see 10.2 Named Attribute Sets), or between
any combination of these constructs. For example, a circularity
exists if a key definition invokes a function that references an
attribute set that calls the key
function, supplying the name of
the original key definition as an argument.
Circularity is not the same as recursion. Stylesheet functions (see 10.3 Stylesheet Functions) and named templates (see 10.1 Named Templates) may call other functions and named templates without restriction. With careless coding, recursion may be non-terminating. Implementations are required to signal circularity as a dynamic error, but they are not required to detect non-terminating recursion.
This section describes three constructs that can be used to provide subroutine-like functionality that can be invoked from anywhere in the stylesheet: named templates (see 10.1 Named Templates), named attribute sets (see 10.2 Named Attribute Sets), and stylesheet functions (see 10.3 Stylesheet Functions).
<!-- Category: instruction
-->
<xsl:call-template
name = eqname >
<!-- Content: xsl:with-param* -->
</xsl:call-template>
[Definition: Templates can be invoked by name. An xsl:template
element with a
name
attribute defines a named
template.] The value of the
name
attribute is an EQName, which is expanded as
described in 5.1 Qualified Names. If an
xsl:template
element
has a name
attribute, it may, but need not, also have
a match
attribute. An xsl:call-template
instruction invokes a template by name; it has a required name
attribute that identifies
the template to be invoked. Unlike xsl:apply-templates
,
the xsl:call-template
instruction does not change the focus.
The match
, mode
and
priority
attributes on an xsl:template
element have no
effect when the template is invoked by an xsl:call-template
instruction. Similarly, the name
and
visibility
attributes on an xsl:template
element have no
effect when the template is invoked by an xsl:apply-templates
instruction.
[ERR XTSE0650] It is a static error if a
stylesheet contains an xsl:call-template
instruction whose name
attribute does not match the
name
attribute of any named template
visible in the containing package (this includes any template defined in
this package, as well as templates accepted from used packages
whose visibility in this package is not hidden
). For
more details of the process of binding the called template, see
<IP_ADDRESS> Binding References to
Components.
[ERR XTSE0660] It is a static error if a package contains more than one non-hidden template with the same name and the same import precedence, unless it also contains a template with the same name and higher import precedence.
[ERR XTSE3340] It is a static error if an
xsl:template
declaration has the name xsl:initial-template
and
contains an xsl:param
that specifies required="yes"
.
The target template for an xsl:call-template
instruction is established using the binding rules described in
<IP_ADDRESS> Binding References to
Components. This will always be a template whose
name
attribute matches the name
attribute
of the xsl:call-template
instruction. It may be a template defined in the same package that
has higher import precedence than any other
template with this name, or it may be a template accepted from a
used package, or (if the template is not defined as
private
or final
) it may be an overriding
template in a package that uses the containing package. The
result of evaluating an xsl:call-template
instruction is the sequence produced by evaluating the sequence constructor contained in
its target template (see 5.8 Sequence Constructors).
The template name xsl:initial-template
is specially
recognized in that it provides a default entry point for stylesheet
execution (see 2.3 Initiating a
Transformation.) A template with this name must not have any xsl:param
children that specify
required="yes"
. In all other respects a template with
this name behaves exactly like a template with any other name.
Parameters are passed to named templates using the xsl:with-param
element as a
child of the xsl:call-template
instruction.
[ERR XTSE0680] In the case of xsl:call-template
, it is
a static error to pass a non-tunnel parameter
named x to a template that does not have a
non-tunnel template parameter
named x, unless the xsl:call-template
instruction is processed with XSLT 1.0 behavior.
This is not an error in the case of xsl:apply-templates
,
xsl:apply-imports
, and
xsl:next-match
; in
these cases the parameter is simply ignored.
The optional tunnel
attribute may be used to
indicate that a parameter is a tunnel parameter. The
default is no
. Tunnel parameters are described in
10.1.2 Tunnel Parameters
[ERR XTSE0690] It is a static error if a
template that is invoked using xsl:call-template
declares a template parameter specifying
required="yes"
and not specifying
tunnel="yes"
, if no value for this parameter is
supplied by the calling xsl:call-template
instruction.
This example defines a named template for a
numbered-block
with a parameter to control the format
of the number.
<xsl:template name="numbered-block"> <xsl:param name="format">1. </xsl:param> <fo:block> <xsl:number format="{$format}"/> <xsl:apply-templates/> </fo:block> </xsl:template> <xsl:template match="ol//ol/li"> <xsl:call-template name="numbered-block"> <xsl:with-param name="format">a. </xsl:with-param> </xsl:call-template> </xsl:template>
[Definition: A parameter passed to a template may be defined as a tunnel parameter. Tunnel parameters have the property that they are automatically passed on by the called template to any further templates that it calls, and so on recursively.] Tunnel parameters thus allow values to be set that are accessible during an entire phase of stylesheet processing, without the need for each template that is used during that phase to be aware of the parameter.
Note:
Tunnel parameters are conceptually similar to dynamically scoped variables in some functional programming languages.
A tunnel parameter is created by using an
xsl:with-param
element that specifies tunnel="yes"
. A template that
requires access to the value of a tunnel parameter must declare it
using an xsl:param
element that also specifies tunnel="yes"
.
On any template call using an xsl:apply-templates
,
xsl:call-template
,
xsl:apply-imports
or xsl:next-match
instruction, a set of tunnel parameters is passed from
the calling template to the called template. This set consists of
any parameters explicitly created using <xsl:with-param
tunnel="yes">
, overlaid on a base set of tunnel
parameters. If the xsl:apply-templates
,
xsl:call-template
,
xsl:apply-imports
or xsl:next-match
instruction has an xsl:template
declaration as an
ancestor element in the stylesheet, then the base set consists of
the tunnel parameters that were passed to that template; otherwise
(for example, if the instruction is within a global variable
declaration, an attribute set declaration, or a stylesheet function), the base set is
empty. If a parameter created using <xsl:with-param
tunnel="yes">
has the same expanded QName as a
parameter in the base set, then the parameter created using
xsl:with-param
overrides the parameter in the base set; otherwise, the parameter
created using xsl:with-param
is added to
the base set.
When a template accesses the value of a tunnel parameter by declaring it with
xsl:param tunnel="yes"
, this does not remove the
parameter from the base set of tunnel parameters that is passed on
to any templates called by this template.
Two sibling xsl:with-param
elements
must have distinct parameter names, even
if one is a tunnel parameter and the other is not.
Equally, two sibling xsl:param
elements representing
template parameters must have distinct parameter names, even if one is a
tunnel parameter and the other is not.
However, the tunnel parameters that are implicitly passed in a
template call may have names that
duplicate the names of non-tunnel parameters that are explicitly
passed on the same call.
Tunnel parameters are not passed in calls to stylesheet functions.
All other options of xsl:with-param
and xsl:param
are available with
tunnel parameters just as with
non-tunnel parameters. For example, parameters may be declared as
mandatory or optional, a default value may be specified, and a
required type may be specified. If any conversion is required from
the supplied value of a tunnel parameter to the required type
specified in xsl:param
,
then the converted value is used within the receiving template, but
the value that is passed on in any further template calls is the
original supplied value before conversion. Equally, any default
value is local to the template: specifying a default value for a
tunnel parameter does not change the set of tunnel parameters that
is passed on in further template calls.
The set of tunnel parameters that is passed to the initial template is empty.
Tunnel parameters are passed unchanged through a built-in template rule (see 6.8 Built-in Template Rules).
If a tunnel parameter is declared in an xsl:param
element with the
attribute tunnel="yes"
, then a dynamic error occurs
[see ERR
XTDE0700] if the set of tunnel parameters passed to the
template does not include a parameter with a matching expanded
QName.
Suppose that the equations in a scientific paper are to be sequentially numbered, but that the format of the number depends on the context in which the equations appear. It is possible to reflect this using a rule of the form:
<xsl:template match="equation"> <xsl:param name="equation-format" select="'(1)'" tunnel="yes"/> <xsl:number level="any" format="{$equation-format}"/> </xsl:template>
At any level of processing above this level, it is possible to determine how the equations will be numbered, for example:
<xsl:template match="appendix"> ... <xsl:apply-templates> <xsl:with-param name="equation-format" select="'[i]'" tunnel="yes"/> </xsl:apply-templates> ... </xsl:template>
The parameter value is passed transparently through all the
intermediate layers of template rules until it reaches the rule
with match="equation"
. The effect is similar to using
a global variable, except that the parameter can take different
values during different phases of the transformation.
<!-- Category: declaration
-->
<xsl:attribute-set
name = eqname
use-attribute-sets? = eqnames
visibility? = "public" | "private" | "final" |
"abstract"
streamable? = "yes" | "no" >
<!-- Content: xsl:attribute* -->
</xsl:attribute-set>
Attribute sets generate named collections of
attributes that can be used repeatedly on different constructed
elements. The xsl:attribute-set
declaration is used to declare attribute sets. The required name
attribute specifies the
name of the attribute set. The value of the name
attribute is an EQName
, which is expanded as described
in 5.1 Qualified Names.
[Definition: An attribute set is defined as a set of
xsl:attribute-set
declarations in the same package that share the same expanded
QName.]
The content of the xsl:attribute-set
element
consists of zero or more xsl:attribute
instructions
that are evaluated to produce the attributes in the set.
Attribute sets are used by specifying a
use-attribute-sets
attribute on the xsl:element
or xsl:copy
instruction, or by
specifying an xsl:use-attribute-sets
attribute on a
literal result element. An attribute set may be defined in terms of
other attribute sets by using the use-attribute-sets
attribute on the xsl:attribute-set
element
itself. The value of the [xsl:]use-attribute-sets
attribute is in each case a whitespace-separated list of names of
attribute sets. Each name is specified as an EQName, which
is expanded as described in 5.1 Qualified
Names.
Specifying a use-attribute-sets
attribute is
broadly equivalent to adding xsl:attribute
instructions
for each of the attributes in each of the named attribute sets to
the beginning of the content of the instruction with the
[xsl:]use-attribute-sets
attribute, in the same order
in which the names of the attribute sets are specified in the
use-attribute-sets
attribute.
More formally, an xsl:use-attribute-sets
attribute
is expanded using the following recursive algorithm, or any
algorithm that produces the same results:
The value of the attribute is tokenized as a list of QNames.
Each QName in the list is processed, in order, as follows:
The QName must match the name
attribute of one or
more xsl:attribute-set
declarations in the stylesheet.
Each xsl:attribute-set
declaration whose name matches is processed as follows. Where two
such declarations have different import precedence,
the one with lower import precedence is processed first. Where two
declarations have the same import precedence, they are processed in
declaration order.
If the xsl:attribute-set
declaration has a use-attribute-sets
attribute, the
attribute is expanded by applying this algorithm recursively.
If the xsl:attribute-set
declaration contains one or more xsl:attribute
instructions,
these instructions are evaluated (following the rules for
evaluating a sequence constructor: see 5.8 Sequence Constructors) to
produce a sequence of attribute nodes. These attribute nodes are
appended to the result sequence.
[ERR XTSE0710] It is a static error if the
value of the use-attribute-sets
attribute of an
xsl:copy
, xsl:element
, or xsl:attribute-set
element, or the xsl:use-attribute-sets
attribute of a
literal result element, is not a
whitespace-separated sequence of EQNames, or if it contains a
QName that does not match the name
attribute of any
xsl:attribute-set
declaration in the stylesheet.
[ERR XTSE0720] It is a static error if an
xsl:attribute-set
element directly or indirectly references itself via the names
contained in the use-attribute-sets
attribute.
The visibility
attribute determines the potential
visibility of the attribute set in packages other than the
containing package. If the visibility
attribute is
present on any of the xsl:attribute-set
declarations making up the definition of an attribute
set (that is, all declarations within the same package sharing
the same name), then it must be present,
with the same value, on every xsl:attribute-set
declaration making up the definition of that attribute
set.
If the visibility
attribute is present with the
value abstract
then there must be no xsl:attribute
children
and no use-attribute-sets
attribute.
An attribute set may be designated as
streamable by including the attribute streamable="yes"
on each xsl:attribute-set
declaration making up the attribute set. If any xsl:attribute-set
declaration for an attribute set has the attribute
streamable="yes"
, then every xsl:attribute-set
declaration for that attribute set must
have the attribute streamable="yes"
.
An attribute set is guaranteed-streamable if every
xsl:attribute-set
declaration making up the attribute set, considered as a sequence constructor, is motionless
according to the analysis in 19.8.5 Classifying Attribute
Sets.
Specifying streamable="yes"
on an xsl:attribute-set
element
declares an intent that the attribute set should be guaranteed
streamable according to these criteria. The consequences of
declaring the attribute set to be streamable when it is not in fact
guaranteed streamable depend on the conformance level of the
processor, and are explained in 19.10 Streamability
Guarantees.
Note:
It is common for attribute sets to create attributes with
constant values, and such attribute sets will always be motionless
and therefore streamable. Although such cases are fairly simple for
a processor to detect, references to attribute sets are not
guaranteed streamable unless the attribute set is declared with the
attribute streamable="yes"
, which should therefore be
used if interoperable streaming is required.
Attribute sets are evaluated as follows:
The xsl:copy
and
xsl:element
instructions have an use-attribute-sets
attribute. The
sequence of attribute nodes produced by evaluating this attribute
is prepended to the sequence produced by evaluating the sequence constructor contained
within the instruction.
Literal result elements allow an
xsl:use-attribute-sets
attribute, which is evaluated
in the same way as the use-attribute-sets
attribute of
xsl:element
and
xsl:copy
. The sequence of
attribute nodes produced by evaluating this attribute is prepended
to the sequence of attribute nodes produced by evaluating the
attributes of the literal result element, which in turn is
prepended to the sequence produced by evaluating the sequence constructor contained with
the literal result element.
The xsl:attribute
instructions are evaluated using the same focus as is used for evaluating the
element that is the parent of the
[xsl:]use-attribute-sets
attribute forming the initial
input to the algorithm. However, the static context for the
evaluation depends on the position of the xsl:attribute
instruction in
the stylesheet: thus, only local variables declared within an
xsl:attribute
instruction, and global variables, are visible.
The set of attribute nodes produced by expanding
xsl:use-attribute-sets
may include several attributes
with the same name. When the attributes are added to an element
node, only the last of the duplicates will take effect.
The way in which each instruction uses the results of expanding
the [xsl:]use-attribute-sets
attribute is described in
the specification for the relevant instruction: see 11.1 Literal Result Elements,
11.2 Creating Element Nodes Using
xsl:element , and 11.9 Copying
Nodes.
The result of evaluating an attribute set is a sequence of attribute nodes. Evaluating the same attribute set more than once can produce different results, because although an attribute set does not have parameters, it may contain expressions or instructions whose value depends on the evaluation context.
Each attribute node produced by expanding an attribute set has a
type annotation determined by the rules for
the xsl:attribute
instruction that created the attribute node: see 11.3.1 Setting the Type
Annotation for a Constructed Attribute Node. These type
annotations may be preserved, stripped, or replaced as determined
by the rules for the instruction that creates the element in which
the attributes are used.
The following example creates a named attribute set
title-style
and uses it in a template rule.
<xsl:template match="chapter/heading"> <fo:block font-stretch="condensed" xsl:use-attribute-sets="title-style"> <xsl:apply-templates/> </fo:block> </xsl:template> <xsl:attribute-set name="title-style"> <xsl:attribute name="font-size">12pt</xsl:attribute> <xsl:attribute name="font-weight">bold</xsl:attribute> </xsl:attribute-set>
The following example creates a named attribute set
base-style
and uses it in a template rule with
multiple specifications of the attributes:
is specified only in the attribute set
is specified in the attribute set, is specified on the literal
result element, and in an xsl:attribute
instruction
is specified in the attribute set, and on the literal result element
is specified in the attribute set, and in an xsl:attribute
instruction
Stylesheet fragment:
<xsl:attribute-set name="base-style"> <xsl:attribute name="font-family">Univers</xsl:attribute> <xsl:attribute name="font-size">10pt</xsl:attribute> <xsl:attribute name="font-style">normal</xsl:attribute> <xsl:attribute name="font-weight">normal</xsl:attribute> </xsl:attribute-set> <xsl:template match="o"> <fo:block xsl:use-attribute-sets="base-style" font-size="12pt" font-style="italic"> <xsl:attribute name="font-size">14pt</xsl:attribute> <xsl:attribute name="font-weight">bold</xsl:attribute> <xsl:apply-templates/> </fo:block> </xsl:template>
Result:
<fo:block font-family="Univers" font-size="14pt" font-style="italic" font-weight="bold"> ... </fo:block>
[Definition: An xsl:function
declaration
declares the name, parameters, and implementation of a
stylesheet function that can be called from any XPath
expression within the stylesheet.]
<!-- Category: declaration
-->
<xsl:function
name = eqname
as? = sequence-type
visibility? = "public" | "private" | "final" |
"abstract"
override-extension-function? = "yes" | "no"
[override]? = "yes" |
"no"
identity-sensitive? = "yes" | "no"
cache? = "full" | "partial" | "no" >
<!-- Content: (xsl:param*, sequence-constructor)
-->
</xsl:function>
The xsl:function
declaration defines a stylesheet function
that can be called from any XPath expression used in the
stylesheet (including an XPath expression used
within a predicate in a pattern). The name
attribute
specifies the name of the function. The value of the
name
attribute is an EQName, which is expanded as
described in 5.1 Qualified Names.
An xsl:function
declaration can only appear as a top-level element in a
stylesheet module.
The content of the xsl:function
element consists
of zero or more xsl:param
elements that specify the formal arguments of the function,
followed by a sequence constructor that defines
the value to be returned by the function.
The name of the function is given by the name
attribute; the arguments are defined by child xsl:param
elements; and the
return type is defined by the as
attribute. Together
these definitions constitute the function signature.
[ERR XTSE0740] It is a static error if a stylesheet function has a name that is in no namespace.
Note:
To prevent the namespace declaration used for the function name
appearing in the result document, use the
exclude-result-prefixes
attribute on the xsl:stylesheet
element: see
11.1.3 Namespace Nodes for Literal
Result Elements.
The name of the function must not be in a reserved namespace: [see ERR XTSE0080]
[Definition: The arity of a
stylesheet function is the number of xsl:param
elements in the
function definition.] Optional
arguments are not allowed.
As defined in XPath, the function that is executed as the result of a function call is identified by looking in the in-scope functions of the static context for a function whose name and arity matches the name and number of arguments in the function call.
Note:
Functions are not polymorphic. Although the XPath function call mechanism allows two functions to have the same name and different arity, it does not allow them to be distinguished by the types of their arguments.
The xsl:param
elements
define the formal arguments to the function. These are interpreted
positionally. When the function is called using a function-call in
an XPath expression, the first argument supplied is
assigned to the first xsl:param
element, the second
argument supplied is assigned to the second xsl:param
element, and so on.
[ERR XTSE0760] Because arguments to a stylesheet
function call must all be specified, the
xsl:param
elements within
an xsl:function
element must not specify a default value:
this means they must be empty, and
must not have a select
attribute.
The as
attribute of the xsl:param
element defines the
required type of the parameter. The rules for converting the values
of the actual arguments supplied in the function call to the types
required by each xsl:param
element are defined in
[XPath 3.0]. The rules that apply are those
for the case where XPath 1.0 compatibility
mode is set to false
.
[ERR XTTE0790] If the value of a parameter to a stylesheet function cannot be converted to the required type, a type error is signaled.
If the as
attribute is omitted, no conversion takes
place and any value is accepted.
The result of the function is the result of evaluating the contained sequence constructor.
Within the sequence constructor, the focus is initially absent; this means that any attempt to reference the context item, context position, or context size is a dynamic error. [ERR XPDY0002] XP30
It is not possible within the body of the stylesheet function to access the values of local variables that were in scope in the place where the function call was written. Global variables, however, remain available.
The optional as
attribute indicates the required
type of the result of the function. The value of the
as
attribute is a SequenceTypeXP30,
as defined in [XPath 3.0].
[ERR XTTE0780] If the as
attribute
is specified, then the result evaluated by the sequence constructor (see 5.8 Sequence Constructors) is
converted to the required type, using the function conversion rules. It
is a type error if this conversion fails. If the
as
attribute is omitted, the calculated result is used
as supplied, and no conversion takes place.
If the visibility
attribute is present with the
value abstract
then the sequence constructor defining the
function body must be empty.
A stylesheet function is included in the in-scope functions of the static context for all XPath expressions used in the containing package, unless
there is another stylesheet function with the same name and arity, and higher import precedence, or
the override-extension-function
or
override
attribute has the value no
and
there is already a function with the same name and arity in the in-scope
functions.
The visibility of the function in other packages
depends on the value of the visibility
attribute and
other factors, as described in 3.6
Packages
The optional
override-extension-function
attribute
defines what happens if this function has the same name and
arity as a
function provided by the implementer or made available in the
static context using an implementation-defined mechanism. If the
override-extension-function
attribute has
the value yes
, then this function is used in
preference; if it has the value no
, then the other
function is used in preference. The default value is
yes
.
Note:
Specifying
override-extension-function="yes"
ensures
interoperable behavior: the same code will execute with all
processors. Specifying
override-extension-function="no"
is
useful when writing a fallback implementation of a function that is
available with some processors but not others: it allows the
vendor's implementation of the function (or a user's implementation
written as an extension function) to be used in preference to the
stylesheet implementation, which is useful when the extension
function is more efficient.
The override-extension-function
attribute does
not affect the rules for deciding which of several
stylesheet functions with the same
name and arity takes precedence.
The override
attribute is a deprecated synonym of
override-extension-function
, retained for
compatibility with XSLT 2.0. If both attributes are present then
they must have the same value.
[ERR XTSE0770] It is a static error for a package to contain two or more non-hidden functions with the same expanded QName, the same arity, and the same import precedence, unless there is another function with the same expanded QName and arity, and a higher import precedence.
When the xsl:function
declaration
appears as a child of xsl:override
, there
must be a stylesheet function with the
same expanded QName and arity in the package referenced by the
containing xsl:use-package
element;
the visibility of that function must be
public
or abstract
, and the overriding
and overridden functions must have the
same argument types and result type.
If a stylesheet function with a particular
expanded QName and arity exists in the stylesheet, then
a call to the
function-lookup
FO30 function
supplying that name and arity will return the function as a value.
This applies only if the static context for the call on
function-lookup
FO30 includes
the stylesheet function, which implies that the function is visible
in the containing package.
The function-available
function, when called with a particular expanded QName and
arity,
returns true if and only if a call on
function-lookup
FO30 with the
same arguments, in the same static context, would return a function
item.
Note:
For legacy reasons there is also a single-argument version of
function-available
,
which returns true if there is a function with the given name
regardless of arity.
The standard rules for
function-lookup
FO30 require
that if the supplied name and arity identify a context-dependent
function such as name#0
FO30
or lang#1
FO30
(call it F), then the returned function value includes
in its closure a copy of the static and dynamic context of the call
to
function-lookup
FO30, and the
context item for a subsequent dynamic call of F is taken
from this saved context. In the case where the context item is a
node in a streamed input document, saving the node is not possible.
In this case, therefore, the context is saved with an absent focus,
so the call on F will fail with a dynamic error saying
that there is no context item available.
Stylesheet functions have been designed to be largely deterministic: unless a stylesheet function calls some extension function which is itself non-deterministic, the function will return results that depend only on the supplied arguments. This property (coupled with the fact that the effect of calling extension functions is entirely implementation-dependent) enables a processor to implement various optimizations, such as removing invariant function calls from the body of a loop, or combining common sub-expressions,.
One exception to the intrinsic determinism of stylesheet
functions arises because constructed nodes have distinct identity.
This means that when a function that creates a new node is called,
two calls on the function will return nodes that can be
distinguished: for example, with such a function,
f:make-node() is f:make-node()
will return false. This
property of functions is called identity-sensitivity. If a
processor cannot determine by static analysis that the function is
not identity-sensitive, then it cannot perform optimizations that
would observably change this behavior.
To allow processors greater freedom to optimize calls on
stylesheet functions, the attribute
identity-sensitive="no"
may be specified (the default
is yes
). When the value no
is specified,
the stylesheet author is asserting that for any node passed in the
value of an argument to the function, and for any node returned as
a result, the stylesheet as a whole will give acceptable results if
the node is replaced by a different node that is deep-equal to the
original.
Note:
Note the term "acceptable". The result of the transformation may be different, but not in a way that the stylesheet author cares about.
Declaring a function with identity-sensitive="no"
might allow a call to the function to be moved out of a loop, so
the function is only called once before entry to the loop rather
than being called repeatedly within the loop. If the arguments to
the function depend only on global variables then it might enable
the function call to be moved into a global variable. It might also
enable some caching or memoization at the processor's
discretion.
Declaring a function with identity-sensitive="no"
might also allow nodes from a streamed input document to be passed
to the function, since the function is licensed to operate on a
deep copy of the node. However, the streamability analysis in this
specification does not take account of this possibility.
The cache
attribute is an optimization hint which
the processor can use or ignore at its discretion; however it
should be taken seriously, because it may make a difference to
whether execution of a stylesheet is practically feasible or
not.
The default value is cache="no".
The value cache="full"
encourages the processor to
retain memory of all previous calls of this function during the
same transformation and to reuse results from this memory whenever
possible. The value cache="partial"
encourages the
processor to retain such memory but to discard results if necessary
to keep the amount of memory used within bounds. The default value
cache="no"
encourages the processor not to retain
memory of previous calls.
In all cases the results must respect the semantics; for example
if an attribute node is supplied as the value of an argument, then
its identity must be assumed to be significant unless (a)
identity-sensitive="no"
is specified, or (b) the
processor is able to determine by static analysis that the identity
of the attribute node makes no difference to the result (for
example, because all references to the argument are atomizing
references).
Note:
Memoization using the cache
attribute may be more
effective if the attribute identity-sensitive="no"
is
also used, as this gives a processor more scope for optimization.
In particular, specifying cache="full"
by itself does
not remove the obligation of a processor to return distinct nodes
on each call of a function, whereas combining this with
identity-sensitive="no"
does remove this
obligation.
The following example creates a recursive stylesheet function named
str:reverse
that reverses the words in a supplied
sentence, and then invokes this function from within a template
rule.
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:str="http://example.com/namespace" version="3.0" exclude-result-prefixes="str"> <xsl:function name="str:reverse" as="xs:string"> <xsl:param name="sentence" as="xs:string"/> <xsl:sequence select="if (contains($sentence, ' ')) then concat(str:reverse(substring-after($sentence, ' ')), ' ', substring-before($sentence, ' ')) else $sentence"/> </xsl:function> <xsl:template match="/"> <output> <xsl:value-of select="str:reverse('DOG BITES MAN')"/> </output> </xsl:template> </xsl:transform>
An alternative way of writing the same function is to implement the conditional logic at the XSLT level, thus:
<xsl:function name="str:reverse" as="xs:string"> <xsl:param name="sentence" as="xs:string"/> <xsl:choose> <xsl:when test="contains($sentence, ' ')"> <xsl:sequence select="concat(str:reverse(substring-after($sentence, ' ')), ' ', substring-before($sentence, ' '))"/> </xsl:when> <xsl:otherwise> <xsl:sequence select="$sentence"/> </xsl:otherwise> </xsl:choose> </xsl:function>
The following example illustrates the use of the as
attribute in a function definition. It returns a string containing
the representation of its integer argument, expressed as a roman
numeral. For example, the function call num:roman(7)
will return the string "vii"
. This example uses the
xsl:number
instruction,
described in 12 Numbering. The
xsl:number
instruction
returns a text node, and the function
conversion rules are invoked to convert this text node to the
type declared in the xsl:function
element, namely
xs:string
. So the text node is atomized to a
string.
<xsl:function name="num:roman" as="xs:string"> <xsl:param name="value" as="xs:integer"/> <xsl:number value="$value" format="i"/> </xsl:function>
XPath 3.0 introduces the ability to pass function items as argument to a function. A function that takes function items as arguments is known as a higher-order function.
The following example is a higher-order function that operates on any tree-structured data, for example an organization chart. Given as input a function that finds the direct subordinates of a node in this tree structure (for example, the direct reports of a manager, or the geographical subdivisions of an administrative area), it determines whether one object is present in the subtree rooted at another object (for example, whether one person is among the staff managed directly or indirectly by a manager, or whether one parcel of land is contained directly or indirectly within another parcel. The function does not check for cycles in the data.
<xsl:function name="f:is-subordinate" as="xs:boolean"> <xsl:param name="superior" as="node()"/> <xsl:param name="subordinate" as="node()"/> <xsl:param name="get-direct-children" as="function(node()) as node()*"/> <xsl:sequence select=" some $sub in $get-direct-children($superior) satisfies ($sub is $subordinate or f:is-subordinate($sub, $subordinate, $get-direct-children))"/> </xsl:function>
Given source data representing an organization chart in the form of elements such as:
<employee id="P57832" manager="P68951"/>
the following function can be defined to get the direct reports of a manager:
<xsl:function name="f:direct-reports" as="element(employee)*"> <xsl:param name="manager" as="element(employee)"/> <xsl:sequence select="$manager/../employee [@manager = $manager/@id]"/> </xsl:function>
It is then possible to test whether one employee $E
reports directly or indirectly to another employee $M
by means of the function call:
f:is-subordinate($M, $E, f:direct-reports#1)
<!-- Category: instruction
-->
<xsl:evaluate
xpath = expression
as? = sequence-type
base-uri? = { uri }
with-params? = expression
context-item? = expression
namespace-context? = expression
schema-aware? = { "yes" | "no" } >
<!-- Content: (xsl:with-param | xsl:fallback)* -->
</xsl:evaluate>
The xsl:evaluate
instruction constructs an XPath expression in the form of a string,
evaluates the expression in a specified context, and returns the
result of the evaluation.
The expression given as the value of the xpath
attribute is evaluated and the result is converted to a string
using the function conversion
rules.
[Definition: The string that results from evaluating the
expression in the xpath
attribute is referred to as
the target expression.]
[ERR XTDE3160] It is a dynamic error if the target expression is not a valid XPath 3.0 expression (that is, if a static error occurs when analyzing the string according to the rules of the XPath 3.0 specification).
The as
attribute, if present, indicates the
required type of the result. If the attribute is absent, the
required type is item()*
, which allows any result. The
result of evaluating the target expression is
converted to the required type using the function conversion rules. This
may cause a type error if conversion is not possible. The
result after conversion is returned as the result of the xsl:evaluate
instruction.
The target expression may contain variable references; the
values of such variables may be supplied using an xsl:with-param
child
instruction if the names of the variables are known statically, or
using a map supplied as the value of the expression in the
with-params
attribute if the names are only known
dynamically. If the with-params
attribute is present
then it must contain an expression whose value, when evaluated, is
of type map(xs:QName, item()*)
(see 21.1 Maps for details of maps).
The static contextXP30 for the target expression is as follows:
XPath 1.0 compatibility mode is false
.
Statically known namespaces and default element/type namespace:
if the namespace-context
attribute is present, then
its value is an expression whose required type is a single
node. The expression is evaluated, and the in-scope namespaces of
the resulting node are used as the statically known namespaces for
the target expression. The binding for the default namespace in the
in-scope namespaces is used as the default namespace for elements
and types in the target expression.
[ERR XTTE3170] It is a type error if the result
of evaluating the namespace-context
attribute of the
xsl:evaluate
instruction is anything other than a single node.
if the namespace-context
attribute is absent, then
the in-scope namespaces of the xsl:evaluate
instruction (with
the exception of any binding for the default namespace) are used as
the statically known namespaces for the target expression, and the
value of the innermost [xsl:]xpath-default-namespace
attribute, if any, is used as the default namespace for elements
and types in the target expression.
Note:
XPath 3.0 allows expanded names to be written in a
context-independent way using the syntax
Q{namespace-uri}local-name
Default function namespace: the standard function namespace.
In-scope schema definitions: if the schema-aware
attribute is present and has the effective value
yes
, then the in-scope schema definitions from the
stylesheet context (that is, the schema definitions imported using
xsl:import-schema
).
Otherwise, the built-in types (see 3.15 Built-in Types).
In-scope variables: the names of the in-scope variables are the
union of the names appearing in the name
attribute of
the contained xsl:with-param
elements, and
the names present as keys in the map obtained by evaluating the
with-params
attribute, if present. The corresponding
type is item()*
in the case of a name found as a key
in the with-params
map, or the type named in the
as
attribute of xsl:with-param
child
(defaulting to item()*
) otherwise.
Note:
Variables declared in the stylesheet in xsl:variable
or xsl:param
elements are
not in-scope within the target expression.
If variable names are present in both the static xsl:with-param
children and
also in the dynamic with-params
map, the value from
the latter takes precedence.
Function signatures: All core functions; constructor
functions for named simple types included in the
in-scope schema definitions; all user-defined functions and
accumulator functions present in the containing package provided
their visibility is not hidden
or
private
; and an implementation-defined set of
extension functions.
Note that this set deliberately excludes XSLT-defined functions
in the standard function namespace
including for example, key
,
current-group
, and
system-property
A
list of these functions is in G List of XSLT-defined
functions.
Statically known collations: the same as the collations available at this point in the stylesheet.
Default collation: the same as the default collation defined at
this point in the stylesheet (for example, by use of the
[xsl:]default-collation
attribute)
Base URI: if the base-uri
attribute is present,
then its effective value; otherwise, the base URI
of the xsl:evaluate
instruction.
Statically known documents: the empty set
Statically known collections: the empty set
Statically known default collection type:
node()*
The dynamic context for evaluation of the target expression is as follows:
The context item, position, and size depend on the result of
evaluating the expression in the context-item
attribute. If this attribute is absent, or if the result is an
empty sequence, then the context item, position, and size for
evaluation of the target expression are all absent. If the result of
evaluating the context-item
expression is a single
item, then the target expression is evaluated with a singleton focus based on this item.
[ERR XTTE3210] If the result of evaluating the
context-item
expression is a sequence containing more
than one item, then a type error is signaled.
The variable values consists of the values bound to
parameters defined either in the contained xsl:with-param
elements,
which are evaluated as described in 9.3 Values of Variables and
Parameters, or in the map that results from evaluation of
the expression in the with-params
attribute; if the
same QName is bound in both, the value in the
with-params
map takes precedence.
The XSLT-specific aspects of the dynamic context described in 5.4.4 Additional Dynamic Context Components used by XSLT are all absent.
All other aspects of the dynamic context are the same as the
dynamic context for the xsl:evaluate
instruction
itself.
xsl:evaluate
instructionThe XPath expression is evaluated in the same execution
scopeFO30 as the calling XSLT
transformation; this means that the results of deterministicFO30
functions such as doc
FO30
or
current-dateTime
FO30 will be
consistent between the calling stylesheet and the called XPath
expression.
It is a dynamic error if evaluation of the XPath expression fails with a dynamic error. The XPath-defined error code is used unchanged.
Note:
Implementations wanting to avoid the cost of repeated compilation of the same XPath expression should cache the compiled form internally.
Stylesheet authors need to be aware of the security risks
associated with the use of xsl:evaluate
. The instruction
should not be used to execute code from an untrusted source. To
avoid the risk of code injection, user-supplied data should never
be inserted into the expression using string concatenation, but
should always be referenced by use of parameters.
xsl:evaluate
as
an optional featureThe xsl:evaluate
instruction is newly introduced in XSLT 3.0. It is part of the
dynamic evaluation feature, which is an optional feature of the
specification (see 26.6
Dynamic Evaluation Feature). An XSLT 3.0 processor
may disable the feature, or allow users
to disable the feature. The processor may
be able to determine during static analysis whether or not the
feature is available, or it may only be
able to determine this during dynamic evaluation. In the first case
we refer to the feature being statically disabled, in the
second case to it being dynamically disabled.
If the feature is statically disabled, then:
A call to element-available('xsl:evaluate')
returns
false, wherever it appears;
A call to
system-property('xsl:supports-dynamic-evaluation')
returns "no", wherever it appears;
If an xsl:evaluate
instruction has an xsl:fallback
child, fallback
processing takes place;
No static error is raised if an xsl:evaluate
instruction is
present in the stylesheet (an error occurs only if it is actually
evaluated).
If the feature is dynamically disabled, then:
A call to element-available('xsl:evaluate')
appearing in a static expression (for example, in an
[xsl:]use-when
attribute) returns true;
A call to element-available('xsl:evaluate')
appearing anywhere else returns false;
A call to
system-property('xsl:supports-dynamic-evaluation')
appearing in a static expression (for example, in an
[xsl:]use-when
attribute) returns "yes";
A call to
system-property('xsl:supports-dynamic-evaluation')
appearing anywhere else returns "no";
If an xsl:evaluate
instruction has an xsl:fallback
child, fallback
processing takes place;
In the absence of an xsl:fallback
child, a dynamic
error is raised if an xsl:evaluate
instruction is
evaluated. The dynamic error may be caught using xsl:try
and xsl:catch
.
[ERR XTDE3175] It is a dynamic error if an
xsl:evaluate
instruction is evaluated when use of xsl:evaluate
has been
statically or dynamically disabled.
In consequence of these rules, the recommended approach for
stylesheet authors to write code that works whether or not xsl:evaluate
is enabled is to
use an xsl:fallback
child instruction. For example:
<xsl:variable name="isValid" as="xs:boolean"> <xsl:evaluate xpath="$validityCondition"> <xsl:fallback><xsl:sequence select="true()"/></xsl:fallback> </xsl:evaluate> </xsl:variable>
Note:
There may be circumstances where it is inappropriate to allow
use of xsl:evaluate
.
For example:
There may be security risks associated with the ability to execute code from an untrusted source, which cannot be inspected during static analysis.
There may be environments where the the available computing resources are sufficient to enable pre-compiled stylesheets to be executed, but not to enable XPath expressions to be compiled into executable code.
Processors that implement xsl:evaluate
should provide
mechanisms allowing calls on xsl:evaluate
to be disabled.
Implementations may disable the feature by default, and they may
disable it unconditionally.
xsl:evaluate
A common requirement is to sort a table on the value of an expression which is selected at run-time, perhaps by supplying the expression as a string-valued parameter to the stylesheet. Suppose that such an expression is supplied to the parameter:
<xsl:param name="sortkey" as="xs:string" select="'@name'"/>
Then the data may be sorted as follows:
<xsl:sort> <xsl:evaluate xpath="$sortkey" as="xs:string" context-item="."/> </xsl:sort>
Note the importance in this use case of caching the compiled expression, since it is evaluated repeatedly, once for each item in the list being sorted.
The
function-lookup
FO30 function,
if it were not available in the standard library, could be
implemented like this:
<xsl:function name="f:function-lookup"> <xsl:param name="name" as="xs:QName"/> <xsl:param name="arity" as="xs:integer"/> <xsl:evaluate xpath="'Q{' || namespace-uri-from-QName($name) || '}' || local-name-from-QName($name) || '#' || $arity"> <xsl:with-param name="name" as="xs:QName" select="$name"/> <xsl:with-param name="arity" as="xs:integer" select="$arity"/> </xsl:evaluate> </xsl:function>
The xsl:evaluate
instruction uses the supplied QName and arity to construct an
expression of the form Q{namespace-uri}local#arity
,
which is then evaluated to return a function item representing the
requested function.
This section describes instructions that directly create new nodes, or sequences of nodes, atomic values, and/or function items.
[Definition: In a sequence constructor, an element in the stylesheet that does not belong to the XSLT namespace and that is not an extension instruction (see 23.2 Extension Instructions) is classified as a literal result element.] A literal result element is evaluated to construct a new element node with the same expanded QName (that is, the same namespace URI, local name, and namespace prefix). The result of evaluating a literal result element is a node sequence containing one element, the newly constructed element node.
The content of the element is a sequence constructor (see 5.8 Sequence Constructors). The sequence obtained by evaluating this sequence constructor, after prepending any attribute nodes produced as described in 11.1.2 Attribute Nodes for Literal Result Elements and namespace nodes produced as described in 11.1.3 Namespace Nodes for Literal Result Elements, is used to construct the content of the element, following the rules in 5.8.1 Constructing Complex Content
The base URI of the new element is copied from the base URI of
the literal result element in the stylesheet, unless the content of
the new element includes an xml:base
attribute, in
which case the base URI of the new element is the value of that
attribute, resolved (if it is a relative URI
reference) against the base URI of the literal result
element in the stylesheet. (Note, however, that this is only
relevant when creating a parentless element. When the literal
result element is copied to form a child of an element or document
node, the base URI of the new copy is taken from that of its new
parent.)
The attributes xsl:type
and
xsl:validation
may be used on a literal result element
to invoke validation of the contents of the element against a type
definition or element declaration in a schema, and to determine the
type annotation that the new element node will
carry. These attributes also affect the type annotation carried by
any elements and attributes that have the new element node as an
ancestor. These two attributes are both optional, and if one is
specified then the other must be
omitted.
The value of the xsl:validation
attribute, if
present, must be one of the values strict
,
lax
, preserve
, or strip
. The
value of the xsl:type
attribute, if present, must be
an EQName identifying a type definition that
is present in the in-scope schema
components for the stylesheet. Neither attribute may be
specified as an attribute value template.
The effect of these attributes is described in 24.2 Validation.
Attribute nodes for a literal result element may be created by
including xsl:attribute
instructions
within the sequence constructor. Additionally,
attribute nodes are created corresponding to the attributes of the
literal result element in the stylesheet, and as a result of
expanding the xsl:use-attribute-sets
attribute of the
literal result element, if present.
The sequence that is used to construct the content of the literal result element (as described in 5.8.1 Constructing Complex Content) is the concatenation of the following four sequences, in order:
The sequence of namespace nodes produced as described in 11.1.3 Namespace Nodes for Literal Result Elements.
The sequence of attribute nodes produced by expanding the
xsl:use-attribute-sets
attribute (if present)
following the rules given in 10.2
Named Attribute Sets
The attributes produced by processing the attributes of the literal result element itself, other than attributes in the XSLT namespace. The way these are processed is described below.
The sequence produced by evaluating the contained sequence constructor, if the element is not empty.
Note:
The significance of this order is that an attribute produced by
an xsl:attribute
, xsl:copy
, or xsl:copy-of
instruction in the
content of the literal result element takes precedence over an
attribute produced by expanding an attribute of the literal result
element itself, which in turn takes precedence over an attribute
produced by expanding the xsl:use-attribute-sets
attribute. This is because of the rules in 5.8.1 Constructing Complex
Content, which specify that when two or more attributes in
the sequence have the same name, all but the last of the duplicates
are discarded.
Although the above rules place namespace nodes before attributes, this is not strictly necessary, because the rules in 5.8.1 Constructing Complex Content allow the namespaces and attributes to appear in any order so long as both come before other kinds of node. The order of namespace nodes and attribute nodes in the sequence has no effect on the relative position of the nodes in document order once they are added to a tree.
Each attribute of the literal result element, other than an attribute in the XSLT namespace, is processed to produce an attribute for the element in the result tree.
The value of such an attribute is interpreted as an attribute value template: it can
therefore contain expressions contained in curly brackets
({}
). The new attribute node will have the same
expanded QName (that is, the same
namespace URI, local name, and namespace prefix) as the attribute
in the stylesheet tree, and its string value will be the same
as the effective value of the attribute in the
stylesheet tree. The type annotation on the attribute will
initially be xs:untypedAtomic
, and the typed
value of the attribute node will be the same as its string
value.
Note:
The eventual type annotation of the attribute in the
result tree depends on the
xsl:validation
and xsl:type
attributes of
the parent literal result element, and on the instructions used to
create its ancestor elements. If the xsl:validation
attribute is set to preserve
or strip
,
the type annotation will be xs:untypedAtomic
, and the
typed
value of the attribute node will be the same as its string
value. If the xsl:validation
attribute is set to
strict
or lax
, or if the
xsl:type
attribute is used, the type annotation on the
attribute will be set as a result of the schema validation process
applied to the parent element. If neither attribute is present, the
type annotation on the attribute will be
xs:untypedAtomic
.
If the name of a constructed attribute is xml:id
,
the processor must perform attribute value normalization by
effectively applying the
normalize-space
FO30 function
to the value of the attribute, and the resulting attribute node
must be given the is-id
property.
Note:
If the attribute name is xml:space
, it is
not an error when the value is something other than
default
or preserve
. Although the XML
specification states that other values are erroneous, a document
containing such values is well-formed; if erroneous values are to
be rejected, schema validation should be used.
Note:
The xml:base
, xml:lang
,
xml:space
, and xml:id
attributes have two
effects in XSLT. They behave as standard XSLT attributes, which
means for example that if they appear on a literal result element,