Template rules define the processing that can be applied to items that match a particular pattern.
<!-- Category: declaration -->
<xsl:template
match? = pattern
name? = eqname
priority? = decimal
mode? = tokens
as? = sequence-type
visibility? = "public" | "private" | "final" | "abstract" >
<!-- Content: (xsl:context-item?, xsl:param*, sequence-constructor) -->
</xsl:template>
[Definition: An xsl:template
declaration defines a template, which contains a sequence constructor;
this sequence constructor is evaluated to determine
the result of the template. A template can serve either as a template rule, invoked by matching items against a pattern, or as a named
template, invoked explicitly by name. It is also possible for the
same template to serve in both capacities.]
[ERR XTSE0500] An xsl:template
element must have either a
match
attribute or a name
attribute, or both. An
xsl:template
element that has no match
attribute must have no mode
attribute and no
priority
attribute. An
xsl:template
element that has no name
attribute must have no visibility
attribute.
If an xsl:template
element has a match
attribute, then
it is a template rule. If it has a
name
attribute, then it is a named
template.
A template may be invoked in a number of ways,
depending on whether it is a template rule,
a named template, or both. The result of
invoking the template is the result of evaluating the sequence constructor contained in the
xsl:template
element (see 5.7 Sequence Constructors).
For details of the optional xsl:context-item
child
element, see 10.1.1 Declaring the Context Item for a Template.
If an as
attribute of the xsl:template
element is
present, the as
attribute defines the required type of the result. The
result of evaluating the sequence
constructor is then converted to the required type using the function conversion rules. If no
as
attribute is specified, the default value is item()*
,
which permits any value. No conversion then takes place.
[ERR XTTE0505] It is a type error if the result of evaluating the sequence constructor cannot be converted to the required type.
If the visibility
attribute is present with the value
abstract
then (a) the sequence constructor
defining the template body must be empty: that is, the only
permitted children are xsl:context-item
and
xsl:param
, and (b) there must be no
match
attribute.
If the parent of the xsl:template
element is an
xsl:override
element, then either or both of the following conditions
must be true:
There is a name
attribute, and the package identified by the containing
xsl:use-package
element contains among its components a named
template whose symbolic
identifier is the same as that of this named template, and which has a compatible signature.
Both the following conditions are true:
There is a match
attribute.
The value of the mode
attribute,
or in its absence the string #default
,
is a whitespace-separated sequence of tokens in which each token satisfies
one of the following conditions:
The token is an EQName representing the name of a mode that is exposed,
with visibility equal to public
, by the package identified by the containing
xsl:use-package
element.
The token is #default
, and there is an ancestor-or-self element with
a default-mode
attribute whose value is an EQName representing the name of a mode that is exposed,
with visibility equal to public
, by the package identified by the containing
xsl:use-package
element.
Note:
The token #unnamed
is not allowed because the unnamed mode never has public visibility.
The token #all
is not allowed because its intended meaning would not be obvious.
This section describes template rules. Named templates are described in 10.1 Named Templates.
A template rule is specified using the
xsl:template
element with a match
attribute. The
match
attribute is a Pattern that identifies
the items to which the rule applies. The result of
applying the template rule is the result of evaluating the sequence constructor
contained in the xsl:template
element, with the matching item used as the context item.
For example, an XML document might contain:
This is an <emph>important</emph> point.
The following template rule matches
emph
elements and produces a fo:wrapper
element with
a font-weight
property of bold
.
<xsl:template match="emph"> <fo:wrapper font-weight="bold" xmlns:fo="http://www.w3.org/1999/XSL/Format"> <xsl:apply-templates/> </fo:wrapper> </xsl:template>
A template rule is evaluated when an
xsl:apply-templates
instruction selects an item that matches the pattern specified in the match
attribute. The xsl:apply-templates
instruction is described in the
next section. If several template rules match a selected item, only one of them is evaluated, as described in 6.4 Conflict Resolution for Template Rules.
<!-- Category: instruction -->
<xsl:apply-templates
select? = expression
mode? = token >
<!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>
The xsl:apply-templates
instruction takes as input a sequence of
items (typically nodes in a source tree), and produces as output a sequence of
items; these will often be nodes to be added to a result tree.
If the instruction has one or more xsl:sort
children, then the input
sequence is sorted as described in 13 Sorting. The result of this sort
is referred to below as the sorted sequence; if there are no
xsl:sort
elements, then the sorted sequence is the same as the
input sequence.
Each item in the input sequence is processed by
finding a template rule whose pattern matches that item. If there is more than one such template rule, the best among them
is chosen, using rules described in 6.4 Conflict Resolution for Template Rules. If there is no
template rule whose pattern matches the item, a
built-in template rule is used (see 6.7 Built-in Template Rules). The chosen
template rule is evaluated. The rule that matches the Nth item in the sorted sequence is evaluated with that
item as the context item, with N as the context position, and with the length of the
sorted sequence as the context size. Each
template rule that is evaluated produces a sequence of items as its result. The
resulting sequences (one for each item in the
sorted sequence) are then concatenated, to form a single sequence. They are
concatenated retaining the order of the items in
the sorted sequence. The final concatenated sequence forms the result of the
xsl:apply-templates
instruction.
Suppose the source document is as follows:
<message>Proceed <emph>at once</emph> to the exit!</message>
This can be processed using the two template rules shown below.
<xsl:template match="message"> <p> <xsl:apply-templates select="child::node()"/> </p> </xsl:template> <xsl:template match="emph"> <b> <xsl:apply-templates select="child::node()"/> </b> </xsl:template>
There is no template rule for the document node; the built-in template rule for
this node will cause the message
element to be processed. The
template rule for the message
element causes a p
element
to be written to the result tree; the
contents of this p
element are constructed as the result of the
xsl:apply-templates
instruction. This instruction selects the
three child nodes of the message
element (a text node containing the
value Proceed
, an emph
element node, and a text node
containing the value to the exit!
). The two text nodes are
processed using the built-in template rule for text nodes, which returns a copy of
the text node. The emph
element is processed using the explicit
template rule that specifies match="emph"
.
When the emph
element is processed, this template rule constructs a
b
element. The contents of the b
element are
constructed by means of another xsl:apply-templates
instruction,
which in this case selects a single node (the text node containing the value
at once
). This is again processed using the built-in template
rule for text nodes, which returns a copy of the text node.
The final result of the match="message"
template rule thus consists
of a p
element node with three children: a text node containing the
value Proceed
, a b
element that is the parent of a
text node containing the value at once
, and a text node containing
the value to the exit!
. This result
tree might be serialized as:
<p>Proceed <b>at once</b> to the exit!</p>
The default value of the select
attribute is child::node()
,
which causes all the children of the context node to be processed.
[ERR XTTE0510] It is a type error if an
xsl:apply-templates
instruction with no select
attribute is evaluated when the context
item is not a node.
A select
attribute can be used to process items selected by an expression instead of processing all children. The
value of the select
attribute is an expression.
The following example processes all of the given-name
children of the
author
elements that are children of
author-group
:
<xsl:template match="author-group"> <fo:wrapper> <xsl:apply-templates select="author/given-name"/> </fo:wrapper> </xsl:template>
It is also possible to process elements that are not descendants of the context
node. This example assumes that a department
element has
group
children and employee
descendants. It finds an
employee’s department and then processes the group
children of
the department
.
<xsl:template match="employee"> <fo:block> Employee <xsl:apply-templates select="name"/> belongs to group <xsl:apply-templates select="ancestor::department/group"/> </fo:block> </xsl:template>
It is possible to write template rules that are matched according to the schema-defined type of an element or attribute. The following example applies different formatting to the children of an element depending on their type:
<xsl:template match="product"> <table> <xsl:apply-templates select="*"/> </table> </xsl:template> <xsl:template match="product/*" priority="3"> <tr> <td><xsl:value-of select="name()"/></td> <td><xsl:next-match/></td> </tr> </xsl:template> <xsl:template match="product/element(*, xs:decimal) | product/element(*, xs:double)" priority="2"> <xsl:value-of select="format-number(xs:double(.), '#,###0.00')"/> </xsl:template> <xsl:template match="product/element(*, xs:date)" priority="2"> <xsl:value-of select="format-date(., '[Mn] [D], [Y]')"/> </xsl:template> <xsl:template match="product/*" priority="1.5"> <xsl:value-of select="."/> </xsl:template>
The xsl:next-match
instruction is described in 6.8 Overriding Template Rules.
Multiple xsl:apply-templates
elements can be used within a single
template to do simple reordering. The following example creates two HTML tables.
The first table is filled with domestic sales while the second table is filled
with foreign sales.
<xsl:template match="product"> <table> <xsl:apply-templates select="sales/domestic"/> </table> <table> <xsl:apply-templates select="sales/foreign"/> </table> </xsl:template>
It is possible for there to be two matching descendants where one is a descendant of the other. This case is not treated specially: both descendants will be processed as usual.
For example, given a source document
<doc><div><div></div></div></doc>
the rule
<xsl:template match="doc"> <xsl:apply-templates select=".//div"/> </xsl:template>
will process both the outer div
and inner div
elements.
This means that if the template rule for the div
element processes
its own children, then these grandchildren will be processed more than once, which
is probably not what is required. The solution is to process one level at a time
in a recursive descent, by using select="div"
in place of
select=".//div"
This example reads a non-XML text file and processes it line-by-line, applying different template rules based on the content of each line:
<xsl:template name="main"> <xsl:apply-templates select="unparsed-text-lines('input.txt')"/> </xsl:template> <xsl:template match=".[starts-with(., '==')]"> <h2><xsl:value-of select="replace(., '==', '')"/></h2> </xsl:template> <xsl:template match=".[starts-with(., '::')]"> <p class="indent"><xsl:value-of select="replace(., '::', '')"/></p> </xsl:template> <xsl:template match="."> <p class="body"><xsl:value-of select="."/></p> </xsl:template>
Note:
The xsl:apply-templates
instruction is most commonly used to
process nodes that are descendants of the context node. Such use of
xsl:apply-templates
cannot result in non-terminating
processing loops. However, when xsl:apply-templates
is used to
process elements that are not descendants of the context node, the possibility
arises of non-terminating loops. For example,
<xsl:template match="foo"> <xsl:apply-templates select="."/> </xsl:template>
Implementations may be able to detect such loops in some cases, but the possibility exists that a stylesheet may enter a non-terminating loop that an implementation is unable to detect. This may present a denial of service security risk.
It is possible for a selected item to match more than one template rule with a given mode M. When this happens, only one template rule is evaluated for the item. The template rule to be used is determined as follows:
First, only the matching template rule or rules with the highest import precedence are considered. Other matching template rules with lower precedence are eliminated from consideration.
Next, of the remaining matching rules, only those with the highest priority are considered. Other matching template rules with lower priority are eliminated from consideration.
[Definition: The priority of a
template rule is specified by the priority
attribute on the
xsl:template
declaration. If no priority is specified
explicitly for a template rule, its default priority is used, as defined in 6.5 Default Priority for Template Rules.]
[ERR XTSE0530] The value of the priority
attribute
must conform to the rules for the
xs:decimal
type defined in [XML Schema Part 2].
Negative values are permitted.
If this leaves more than one matching template rule, then:
If the mode
M has an xsl:mode
declaration, and the
attribute value on-multiple-match="fail"
is specified in the
mode declaration, a dynamic error is signaled. The error is treated as
occurring in the xsl:apply-templates
instruction, and
can be recovered by wrapping that instruction in an
xsl:try
instruction.
[ERR XTDE0540] It is a dynamic error if the
conflict resolution algorithm for template rules leaves more than
one matching template rule when the
declaration of the relevant mode has an on-multiple-match
attribute with the value fail
.
Otherwise, of the matching template rules that remain, the one that occurs last in declaration order is used.
Note:
This was a recoverable error in XSLT 2.0, meaning that it was
implementation-defined whether the error was signaled, or whether the
ambiguity was resolved by taking the last matching rule in declaration
order. In XSLT 3.0 this situation is not an error unless the
attribute value on-multiple-match="fail"
is specified in the
mode declaration. It is also possible to request warnings when this
condition arises, by means of the attribute warning-on-multiple-match="yes"
.
[Definition: If no priority
attribute is specified on an xsl:template
element, a
default priority is computed, based on the syntax of the pattern supplied in the match
attribute.] The rules are as follows.
If the top-level pattern is a ParenthesizedExprP then the outer parentheses are effectively stripped; these rules are applied recursively to the UnionExprP contained in the ParenthesizedExprP.
If the top-level pattern is a UnionExprP consisting
of multiple alternatives separated by |
or union
,
then the template rule is treated equivalently to a set of template rules, one
for each alternative.
These template rules are adjacent to each
other in declaration order, and the declaration order within this set of
template rules (which affects the result of xsl:next-match
if the alternatives have the same default priority) is the order of
alternatives in the UnionExprP.
Note:
The splitting of a template rule into multiple rules occurs only if there is
no explicit priority
attribute.
If the top-level pattern is an IntersectExceptExprP containing two or more PathExprP operands separated by intersect
or
except
operators, then the priority of the pattern is that of
the first PathExprP.
If the pattern is a PredicatePattern then its priority is 1 (one), unless the PredicateListXP30 is empty, in which case the priority is −1 (minus one).
If the pattern is a PathExprP taking the form
/
, then the priority is −0.5 (minus 0.5).
If the pattern is a PathExprP taking the form of an
EQName optionally preceded by a ForwardAxisP or has the form
processing-instruction(
StringLiteralXP30
)
or processing-instruction(
NCNameNames
)
optionally preceded by a ForwardAxisP, then the priority is 0 (zero).
If the pattern is a PathExprP taking the form of an
ElementTestXP30 or AttributeTestXP30, optionally
preceded by a ForwardAxisP, then the priority is as
shown in the table below. In this table, the symbols E,
A, and T represent an arbitrary element name, attribute
name, and type name respectively, while the symbol *
represents
itself. The presence or absence of the symbol ?
following a type
name does not affect the priority.
Format | Priority | Notes |
---|---|---|
element()
|
−0.5 | (equivalent to * )
|
element(*)
|
−0.5 | (equivalent to * )
|
attribute()
|
−0.5 | (equivalent to @* )
|
attribute(*)
|
−0.5 | (equivalent to @* )
|
element(E)
|
0 | (equivalent to E) |
element(*,T)
|
0 | (matches by type only) |
attribute(A)
|
0 | (equivalent to @A )
|
attribute(*,T)
|
0 | (matches by type only) |
element(E,T)
|
0.25 | (matches by name and type) |
schema-element(E)
|
0.25 | (matches by substitution group and type) |
attribute(A,T)
|
0.25 | (matches by name and type) |
schema-attribute(A)
|
0.25 | (matches by name and type) |
If the pattern is a PathExprP taking the form of a DocumentTestXP30, then if it includes no ElementTestXP30 or SchemaElementTestXP30 the priority is −0.5. If it does include an ElementTestXP30 or SchemaElementTestXP30, then the priority is the same as the priority of that ElementTestXP30 or SchemaElementTestXP30, computed according to the table above.
If the pattern is a PathExprP taking the form of an
NCNameNames:*
or
*:
NCNameNames, optionally
preceded by a ForwardAxisP, then the priority is
−0.25.
If the pattern is a PathExprP taking the form of any other NodeTestXP30, optionally preceded by a ForwardAxisP, then the priority is −0.5.
In all other cases, the priority is +0.5.
Note:
In many cases this means that highly selective patterns have higher priority than less selective patterns. The most common kind of pattern (a pattern that tests for a node of a particular kind, with a particular expanded QName or a particular type) has priority 0. The next less specific kind of pattern (a pattern that tests for a node of a particular kind and an expanded QName with a particular namespace URI) has priority −0.25. Patterns less specific than this (patterns that just test for nodes of a given kind) have priority −0.5. Patterns that specify both the name and the required type have a priority of +0.25, putting them above patterns that only specify the name or the type. Patterns more specific than this, for example patterns that include predicates or that specify the ancestry of the required node, have priority 0.5.
However, it is not invariably true that a more selective pattern has higher
priority than a less selective pattern. For example, the priority of the pattern
node()[self::*]
is higher than that of the pattern
salary
. Similarly, the patterns attribute(*,
xs:decimal)
and attribute(*, xs:short)
have the same
priority, despite the fact that the latter pattern matches a subset of the nodes
matched by the former. Therefore, to achieve clarity in a stylesheet it is good practice to allocate
explicit priorities.
[Definition: A mode is a set of template rules;
when the xsl:apply-templates
instruction selects a set of items
for processing, it identifies the rules to be used for processing those items by
nominating a mode, explicitly or implicitly.] Modes allow a node in a
source tree (for example) to be processed
multiple times, each time producing a different result. They also allow different
sets of template rules to be active when
processing different trees, for example when processing documents loaded using the
document
function (see 20.1 fn:document).
Modes are identified by an expanded QName; in addition to any named modes, there is always one
unnamed mode available. Whether a mode is named or unnamed, its properties
may be defined in an xsl:mode
declaration. If
a mode name is used (for example in an xsl:template
declaration or
an xsl:apply-templates
instruction) and no declaration of that mode
appears in the stylesheet, the mode is implicitly declared with default
properties.
<!-- Category: declaration -->
<xsl:mode
name? = eqname
streamable? = boolean
use-accumulators? = tokens
on-no-match? = "deep-copy" | "shallow-copy" | "deep-skip" | "shallow-skip" | "text-only-copy"
| "fail"
on-multiple-match? = "use-last" | "fail"
warning-on-no-match? = boolean
warning-on-multiple-match? = boolean
typed? = boolean | "strict" | "lax" | "unspecified"
visibility? = "public" | "private" | "final" />
[Definition: The unnamed mode is the default mode used when no
mode
attribute is specified on an
xsl:apply-templates
instruction or
xsl:template
declaration, unless a different default mode
has been specified using the [xsl:]default-mode
attribute of a containing
element.]
Every mode other than the unnamed mode is identified by an expanded QName.
A stylesheet may contain multiple
xsl:mode
declarations and may include or import stylesheet modules that also contain
xsl:mode
declarations. The name of an
xsl:mode
declaration is the value of its name
attribute, if any.
[Definition: All the
xsl:mode
declarations in a package that share the same
name are grouped into a named mode definition; those that have no
name are grouped into a single unnamed mode definition.]
The declared-modes
attribute of
the xsl:package
element determines whether implicit mode
declarations are allowed, as described in 3.5.4.1 Requiring Explicit Mode Declarations. If the package allows implicit mode
declarations, then if a stylesheet does not contain a declaration of the unnamed mode, a
declaration is implied equivalent to an xsl:mode
element with
no attributes. Similarly, if there
is a mode that is named in an xsl:template
or
xsl:apply-templates
element, or in the [xsl:]default-mode
attribute of a containing
element, and the stylesheet
does not contain a declaration of that mode, then a declaration is implied
comprising an xsl:mode
element with a name
attribute
equal to that mode name, plus the attribute
visibility="private"
.
The attributes of the xsl:mode
declaration establish values for a
number of properties of a mode. The allowed values and meanings of the attributes
are given in the following table.
Attribute | Values | Meaning |
---|---|---|
name | An EQName | Specifies the name of the mode. If omitted, this
xsl:mode declaration provides properties of the
unnamed mode |
streamable | yes or no (default
no )
|
Determines whether template rules in this mode are to be
capable of being processed using streaming. If the
value yes is specified, then the body of any template rule that uses this mode
must conform to the rules for streamable templates
given in 6.6.4 Streamable Templates.
|
use-accumulators | List of accumulator names, or #all (default is an empty list)
|
Relevant only when this mode is the initial mode of the transformation, determines which accumulators are applicable to documents containing nodes in the initial match selection. For further details see 18.2.2 Applicability of Accumulators. |
on-no-match | One of deep-copy ,
shallow-copy , deep-skip ,
shallow-skip , text-only-copy or
fail (default
text-only-copy ) |
Determines selection of the built-in template rules that are used to
process an item when an
xsl:apply-templates instruction selects an item that does not match any
user-written template rule in
the stylesheet. For details, see
6.7 Built-in Template Rules.
|
on-multiple-match | One of fail or use-last (default
use-last )
|
Defines the action to be taken when
xsl:apply-templates is used in this mode and more
than one user-written template
rule is available to process an item, each having the same import precedence and priority. The value fail
indicates that it is a dynamic error if more
than one template rule matches an
item. The value use-last indicates that the
situation is not to be treated as an error (the last template in declaration order is the one that
is used).
|
warning-on-no-match | One of yes or no . The default is
implementation-defined
|
Requests the processor to output (or not to output) a warning message in
the case where an xsl:apply-templates instruction
selects an item that matches
no user-written template rule. The form and destination of such warnings
is implementation-defined. The processor
may ignore this attribute, for example if the
environment provides no suitable means of communicating with the user.
|
warning-on-multiple-match | One of yes or no . The default is
implementation-defined
|
Requests the processor to output a warning message in the case where an
xsl:apply-templates instruction selects an item that matches multiple
template rules having the same import
precedence and priority. The form and destination of such warnings is
implementation-defined. The processor
may ignore this attribute, for example if the
environment provides no suitable means of communicating with the
user.
|
typed | One of yes , no ,
strict , lax , or unspecified .
The default is unspecified .
|
See 6.6.3 Declaring the Type of Nodes Processed by a Mode. |
visibility | One of public , private , or
final . The default is private .
|
See 3.5.3.1 Visibility of Components. If the mode is unnamed, that is, if the
name attribute is absent, then the
visibility attribute if present
must have the value
private . A
named mode is not
eligible to be used as the initial mode if its
visibility is private . |
[Definition: A streamable
mode is a mode that is declared in
an xsl:mode
declaration with the attribute
streamable="yes"
.]
For any named mode, the effective value of each
attribute is taken from an xsl:mode
declaration that has a
matching name in its name
attribute, and that specifies an explicit
value for the required attribute. If there is
no such declaration, the default value of the attribute is used. If
there is more than one such declaration, the one with highest import precedence is used.
For the unnamed mode, the effective value
of each attribute is taken from an xsl:mode
declaration that has
no name
attribute, and that specifies an explicit value for the
required attribute. If there is no such declaration, the default value of the
attribute is used. If there is more than one such declaration, the one with
highest import precedence is
used.
[ERR XTSE0545] It is a static error if for any
named or unnamed mode, a package explicitly specifies two conflicting
values for the same attribute in different xsl:mode
declarations having the same import
precedence, unless there is another definition of the same
attribute with higher import precedence. The attributes in question are the
attributes other than name
on the xsl:mode
element.
[Definition: A template rule is applicable to one or more modes.
The modes to which it is applicable are defined by the mode
attribute of the xsl:template
element. If the attribute is
omitted, then the template rule is applicable to the default mode specified in the [xsl:]default-mode
attribute of the innermost containing
element that has such an attribute, which in turn defaults to
the unnamed mode. If the
mode
attribute is present, then its value
must be a non-empty whitespace-separated list of tokens,
each of which defines a mode to which the template rule is
applicable.]
Each token in the mode
attribute must be one of
the following:
an EQName, which is expanded as described in 5.1.1 Qualified Names to define the name of the mode
the token #default
, to indicate that the template rule is
applicable to the default mode that would apply if
the mode
attribute were absent
the token #unnamed
, to indicate that the
template rule is applicable to the unnamed
mode
the token #all
, to indicate that the template rule is
applicable to all modes (specifically, to the unnamed mode and to every mode that is named explicitly or implicitly in an
xsl:apply-templates
instruction anywhere in
the stylesheet).
When a template rule specifies mode="#all"
this is interpreted as meaning all modes declared
implicitly or explicitly within the declaring
package of the xsl:template
element. This value
cannot be used in the case of a template rule declared within an
xsl:override
element.
[ERR XTSE0550] It is a static error if the list of
modes is empty, if the same token is included more than once in the
list, if the list contains an invalid token, or if the token
#all
appears together with any other value.
[ERR XTSE3440] In the case of a template rule (that is, an
xsl:template
element having a match
attribute) appearing as a child of xsl:override
, it is a
static error if the list of
modes in the mode
attribute contains #all
or
#unnamed
, or if it contains #default
and the
default mode is the unnamed mode, or if the
mode
attribute is omitted when the default mode is the
unnamed mode.
The xsl:apply-templates
element also has an optional
mode
attribute. The value of this attribute
must be one of the following:
an EQName, which is expanded as described in 5.1.1 Qualified Names to define the name of a mode
the token #default
, to indicate that the default mode for the stylesheet
module
is to be used
the token #unnamed
, to indicate that the
unnamed mode is to be used
the token #current
, to indicate that the current mode is to be used
If the attribute is omitted, the default mode for the stylesheet module is used.
When searching for a template rule to process each item selected by the xsl:apply-templates
instruction, only those template rules that are applicable to the selected mode
are considered.
[Definition: At any point in the processing
of a stylesheet, there is a current mode. When the transformation
is initiated, the current mode is the initial mode, as described in 2.3 Initiating a Transformation. Whenever an xsl:apply-templates
instruction is evaluated, the current mode becomes the mode selected by this
instruction.] When a non-contextual function call is made, the current mode
is set to the unnamed mode. While
evaluating global variables and parameters, and the sequence constructor contained
in xsl:key
or xsl:sort
, the current mode is set
to the unnamed mode. No other instruction changes the current mode. The current
mode while evaluating an attribute set
is the same as the current mode of the caller. On completion of the
xsl:apply-templates
instruction, or on return from a
stylesheet function call, the current mode reverts to its previous value. The
current mode is used when an xsl:apply-templates
instruction uses
the syntax mode="#current"
; it is also used by the
xsl:apply-imports
and xsl:next-match
instructions (see 6.8 Overriding Template Rules).
Typically the template rules in a particular mode will be
designed to process a specific kind of input document. The typed
attribute of xsl:mode
gives the stylesheet author the opportunity
to provide information about this document to the processor. This information may
enable the processor to improve diagnostics or to optimize performance.
The typed
attribute of xsl:mode
informs the
processor whether the nodes to be processed by template rules in this mode are to
be typed or untyped.
If the value yes
is specified (synonyms true
or
1
), then all nodes processed in this mode must be typed. A
dynamic error occurs if xsl:apply-templates
in this mode
selects an element or attribute node whose type annotation is xs:untyped
or xs:untypedAtomic
.
If the value no
is specified (synonyms false
or
0
), then all nodes processed in this mode must be untyped. A
dynamic error occurs if xsl:apply-templates
in this mode
selects an element or attribute whose type annotation is
anything other than xs:untyped
or
xs:untypedAtomic
.
The value strict
is equivalent to yes
, with the
additional provision that in the match pattern of any template rule that is
applicable to this mode, any NameTest
used in the ForwardStepP
of the first StepExprP
of
a RelativePathExprP
is interpreted as follows:
If the NameTest
is an EQName
E, and the principal node kind of the axis of this step is
Element
, then:
It is a static error if the in-scope schema declarations do not include a global element declaration for element name E
When matching templates in this mode, the element name
E appearing in this step is interpreted as
schema-element(E)
. (Informally, this means
that it will only match an element if it has been validated
against this element declaration).
Otherwise (the NameTest
is a wildcard or the principal
node kind is Attribute
or Namespace
), the
template matching proceeds as if the typed
attribute were
absent.
The value lax
is equivalent to yes
, with the
additional provision that in the match pattern of any template rule that is
applicable to this mode, any NameTest
used in the ForwardStepP
of the first StepExprP
of
a RelativePathExprP
is interpreted as follows:
If the NameTest
is an EQName
E, and the principal node kind of the axis of this step is
Element
, and the in-scope schema declarations include
a global element declaration for element name E, then:
When matching templates in this mode, the element name
E appearing in this step is interpreted as
schema-element(E)
. (Informally, this means
that it will only match an element if it has been validated
against this element declaration).
Otherwise (the NameTest
is a wildcard, or the principal
node kind is Attribute
or Namespace
, or
there is no element declaration for E), the template
matching proceeds as if the typed
attribute were absent.
[ERR XTTE3100] It is a type error if an
xsl:apply-templates
instruction in a particular
mode
selects an element or attribute whose type is
xs:untyped
or xs:untypedAtomic
when the
typed
attribute of that mode specifies the value
yes
, strict
, or lax
.
[ERR XTSE3105] It is a static error if a template
rule applicable to a mode that is defined with typed="strict"
uses a match pattern that contains a RelativePathExprP
whose
first StepExprP
is an AxisStepP
whose
ForwardStepP
uses an axis whose principal node kind is
Element
and whose NodeTest
is an
EQName
that does not correspond to the name of any global
element declaration in the in-scope schema components.
[ERR XTTE3110] It is a type error if an
xsl:apply-templates
instruction in a particular
mode
selects an element or attribute whose type is anything
other than xs:untyped
or xs:untypedAtomic
when the
typed
attribute of that mode specifies the value
no
.
A template rule that is applicable to a mode M is guaranteed-streamable if and only if all the following conditions are satisfied:
Mode M is declared in an xsl:mode
declaration
that specifies streamable="yes"
.
The pattern defined in the
match
attribute of the xsl:template
element
is a motionless
pattern as defined in 19.8.10 Classifying Patterns.
The sweep of the sequence constructor forming the body of the xsl:template
element is either
motionless or consuming.
The type-adjusted
posture of the sequence constructor forming
the body of the xsl:template
element, with respect to the
U-type that corresponds to the declared return type of
the template (defaulting to item()*
), is grounded.
Note:
This means that either (a) the sequence constructor is grounded as written (that is, it does not return streamed nodes), or (b) it effectively becomes grounded because the declared result type of the template is atomic, leading to implicit atomization of the result.
Every expression and contained
sequence constructor in a contained
xsl:param
element (the construct that provides the
default value of the parameter) is
motionless.
Specifying streamable="yes"
on an
xsl:mode
declaration declares an intent that every template
rule that includes that mode (explicitly or implicitly, including by specifying
#all
), should be streamable,
either because it is guaranteed-streamable, or because it
takes advantage of streamability extensions offered by a particular
processor. The consequences of declaring the mode to be streamable
when there is such a template rule that is not guaranteed streamable depend on the
conformance level of the processor, and are explained in 19.10 Streamability Guarantees.
Processing of a document using streamable templates may be
initiated using code such as the following, where S
is a mode
declared with streamable="yes"
:
<xsl:source-document streamable="yes" href="bigdoc.xml"> <xsl:apply-templates mode="S"/> </xsl:source-document>
Alternatively, streamed processing may be initiated by invoking the transformation with an initial mode declared as streamable, while supplying the initial match selection (in an implementation-defined way) as a streamed document.
Note:
Invoking a streamable template using the construct
<xsl:apply-templates select="doc('bigdoc.xml')"/>
does
not ensure streamed processing. As always, processors may use streamed
processing if they are able to do so, but when the doc
FO30
or document
functions are used, processors are obliged to
ensure that the results are deterministic, which may be difficult to reconcile
with streaming (if the same document is read twice, the results must be
identical). The use of xsl:source-document
with streamable="yes"
does not offer the same guarantees of determinism.
For an example of processing a collection of documents by use of the function
uri-collection
FO30 in conjunction with
xsl:source-document
, see 18.1.2 Examples of xsl:source-document.
When an item is
selected by xsl:apply-templates
and there is no user-specified
template rule in the stylesheet that can be used to process that item, then a built-in template rule is
evaluated instead.
The built-in template rules have lower import precedence than all other template rules. Thus, the stylesheet author can override a built-in template rule by including an explicit template rule.
There are six sets of built-in template rules available. The set
that is chosen is a property of the mode selected by
the xsl:apply-templates
instruction. This property is set using the
on-no-match
attribute of the xsl:mode
declaration,
which takes one of the six values deep-copy
, shallow-copy
,
deep-skip
, shallow-skip
, text-only-copy
, or
fail
, the default being text-only-copy
. The effect of
these six sets of built-in template rules is explained in the following
subsections.
The effect of processing a
tree using a mode that specifies
on-no-match="text-only-copy"
is that the textual
content of the source document is retained while losing the markup, except where
explicit template rules dictate otherwise. When an element is encountered for
which there is no explicit template
rule, the processing continues with the children of that element. Text
nodes are copied to the output.
The built-in rule for document nodes and element nodes is equivalent to calling
xsl:apply-templates
with no select
attribute, and
with the mode
attribute set to #current
. If the built-in
rule was invoked with parameters, those parameters are passed on in the implicit
xsl:apply-templates
instruction.
This is equivalent to the following in the case where there are no parameters:
<xsl:template match="document-node()|element()" mode="M"> <xsl:apply-templates mode="#current"/> </xsl:template>
The built-in template rule for text and attribute nodes returns a text node containing the string value of the context node. It is effectively:
<xsl:template match="text()|@*" mode="M"> <xsl:value-of select="string(.)"/> </xsl:template>
Note:
This text node may have a string value that is zero-length.
The built-in template rule for atomic values returns a text node containing the value. It is effectively:
<xsl:template match=".[. instance of xs:anyAtomicType]" mode="M"> <xsl:value-of select="string(.)"/> </xsl:template>
Note:
This text node may have a string value that is zero-length.
The built-in template rule for processing instructions, comments, and namespace nodes does nothing (it returns the empty sequence).
<xsl:template match="processing-instruction()|comment()|namespace-node()" mode="M"/>
The built-in template rule for functions (including maps) does nothing (it returns the empty sequence).
<xsl:template match=".[. instance of function(*)]" mode="M"/>
The built-in template rule for
arrays (see 27.7.1 Arrays) is to apply templates to the members of the array.
It is equivalent to invoking xsl:apply-templates
with the select
attribute set to ?*
(which selects the members of the array), and with the
mode
attribute set to #current
. If the built-in
rule was invoked with parameters, those parameters are passed on in the implicit
xsl:apply-templates
instruction.
This is equivalent to the following in the case where there are no parameters:
<xsl:template match=".[. instance of array(*)]" mode="M"> <xsl:apply-templates mode="#current" select="?*"/> </xsl:template>
The following example illustrates the use of built-in template rules when there are parameters.
Suppose the stylesheet contains the following instruction:
<xsl:apply-templates select="title" mode="M"> <xsl:with-param name="init" select="10"/> </xsl:apply-templates>
If there is no explicit template rule that matches the title
element, then the following implicit rule is used:
<xsl:template match="title" mode="M"> <xsl:param name="init"/> <xsl:apply-templates mode="#current"> <xsl:with-param name="init" select="$init"/> </xsl:apply-templates> </xsl:template>
The effect of processing a tree using a
mode that specifies
on-no-match="deep-copy"
is that an unmatched element
in the source tree is copied unchanged to the output, together with its entire
subtree. Other unmatched items are also copied unchanged. The subtree is copied
unconditionally, without attempting to match nodes in the subtree against template
rules.
When this default action is selected for a mode M, all items (nodes, atomic values, and functions, including maps and arrays) are processed using a template rule that is equivalent to the following:
<xsl:template match="." mode="M"> <xsl:copy-of select="." validation="preserve"/> </xsl:template>
The effect of processing a tree using a
mode that specifies
on-no-match="shallow-copy"
is that the source tree is
copied unchanged to the output, except for nodes where different processing is
specified using an explicit template
rule.
When this default action is selected for a mode M, all items (nodes, atomic values, and functions, including maps and arrays) are processed
using a template rule that is equivalent to the following, except that all
parameters supplied in xsl:with-param
elements are passed on
implicitly to the called templates:
<xsl:template match="." mode="M"> <xsl:copy validation="preserve"> <xsl:apply-templates select="@*" mode="M"/> <xsl:apply-templates select="node()" mode="M"/> </xsl:copy> </xsl:template>
This rule is often referred to as the identity template, though it should be noted that it does not preserve node identity.
Note:
This rule differs from the traditional identity template rule by using two
xsl:apply-templates
instructions, one to process the
attributes and one to process the children. The only observable difference from
the traditional select="node() | @*"
is that with two separate
instructions, the value of position()
in the called templates
forms one sequence starting at 1 for the attributes, and a new sequence
starting at 1 for the children.
The following stylesheet transforms an input document by deleting all elements
named note
, together with their attributes and descendants:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:mode on-no-match="shallow-copy" streamable="true"/> <xsl:template match="note"> <!-- no action --> </xsl:template> </xsl:stylesheet>
The effect of processing a tree using a mode that specifies
on-no-match="deep-skip"
is that where no explicit template rule is
specified for an element, that element and all its descendants are ignored, and
are not copied to the result tree.
The effect of choosing on-no-match="deep-skip"
is as follows:
The built-in rule for document nodes is equivalent to calling
xsl:apply-templates
with no select
attribute, and with the mode
attribute set to
#current
. If the built-in rule was invoked with parameters,
those parameters are passed on in the implicit
xsl:apply-templates
instruction.
In the case where there are no parameters, this is equivalent to the following rule:
<xsl:template match="document-node()" mode="M"> <xsl:apply-templates mode="#current"/> </xsl:template>
The built-in rule for all items other than document nodes (that is, for all other kinds of node, as well as atomic values and functions, including maps and and arrays) is to do nothing, that is, to return an empty sequence (without applying templates to any children or ancestors).
This is equivalent to the following rule:
<xsl:template match="." mode="M"/>
The effect of processing a tree using a
mode that specifies
on-no-match="shallow-skip"
is to drop both the textual
content and the markup from the result document, except where there is an explicit
user-written template rule that dictates
otherwise.
The built-in rule for document nodes and element nodes applies templates (in the current mode) first to the node’s
attributes and then to its children. If the built-in rule was invoked
with parameters, those parameters are passed on in the implicit
xsl:apply-templates
instructions.
In the case where there are no parameters, this is equivalent to the following rule:
<xsl:template match="document-node()|element()" mode="M"> <xsl:apply-templates select="@*" mode="#current"/> <xsl:apply-templates mode="#current"/> </xsl:template>
The built-in template rule for all other kinds of node, and for atomic values and functions (including maps, but not arrays) is empty: that is, when the item is matched, the built-in template rule returns an empty sequence.
This is equivalent to the following rule:
<xsl:template match="." mode="M"/>
The built-in template rule for
arrays (see 27.7.1 Arrays) is to apply templates to the members of the array.
It is equivalent to invoking xsl:apply-templates
with the select
attribute set to ?*
(which selects the members of the array), and with the
mode
attribute set to #current
. If the built-in
rule was invoked with parameters, those parameters are passed on in the implicit
xsl:apply-templates
instruction.
This is equivalent to the following in the case where there are no parameters:
<xsl:template match=".[. instance of array(*)]" mode="M"> <xsl:apply-templates mode="#current" select="?*"/> </xsl:template>
The effect of choosing on-no-match="fail"
for a
mode is that every item selected in an xsl:apply-templates
instruction
must be matched by an explicit user-written template rule.
The built-in template rule is effectively:
<xsl:template match="." mode="M"> <xsl:message terminate="yes" error-code="err:XTDE0555"/> </xsl:template>
with an implementation-dependent message body.
[ERR XTDE0555] It is a dynamic error if
xsl:apply-templates
, xsl:apply-imports
or xsl:next-match
is used to process a node using a mode
whose declaration specifies on-no-match="fail"
when there is no
template rule in the stylesheet
whose match pattern matches that node.
<!-- Category: instruction -->
<xsl:apply-imports>
<!-- Content: xsl:with-param* -->
</xsl:apply-imports>
<!-- Category: instruction -->
<xsl:next-match>
<!-- Content: (xsl:with-param | xsl:fallback)* -->
</xsl:next-match>
A template rule that is being used to
override another template rule (see 6.4 Conflict Resolution for Template Rules) can use the
xsl:apply-imports
or xsl:next-match
instruction
to invoke the overridden template rule. The xsl:apply-imports
instruction only considers template rules in imported stylesheet modules; the
xsl:next-match
instruction considers all other template rules of
lower import precedence and/or
priority, and also declarations of the same
precedence and priority that appear earlier in declaration order. Both instructions will invoke the built-in template rule for the
context item (see 6.7 Built-in Template Rules) if no other template rule is found.
[Definition: At any point in
the processing of a stylesheet, there may
be a current template rule. Whenever a template rule is chosen as a result of
evaluating xsl:apply-templates
,
xsl:apply-imports
, or xsl:next-match
, the
template rule becomes the current template rule for the evaluation of the rule’s
sequence constructor.]
The current template rule is cleared (becomes absent) by any instruction that evaluates an operand with changed focus. It is therefore cleared when evaluating instructions contained within:
xsl:copy
if and only if there is a select
attribute
A global xsl:variable
or xsl:param
xsl:template
if and only if the called template specifies <xsl:context-item use="absent"/>
Note:
The current template rule is not affected by invoking named attribute sets (see 10.2 Named Attribute Sets), or named templates (see 10.1 Named Templates) unless <xsl:context-item use="absent"/>
is specified.
While evaluating a global variable or the default value of a stylesheet parameter (see 9.5 Global Variables and Parameters) the current template rule is absent.
These rules ensure that when xsl:apply-imports
or
xsl:next-match
is called, the context item is the same as when the current template rule was
invoked.
Both xsl:apply-imports
and xsl:next-match
search
for a template rule that matches the
context
item, and that is applicable to the current mode (see 6.6 Modes). In
choosing a template rule, they use the usual criteria such as the priority and
import precedence of the template
rules, but they consider as candidates only a subset of the template rules in the
stylesheet. This subset differs between the
two instructions:
The xsl:apply-imports
instruction considers as candidates only
those template rules contained in stylesheet
levels that are descendants in the import tree of the stylesheet
level that contains the current template rule.
Note:
This is not the same as saying that the search considers all template rules whose import precedence is lower than that of the current template rule.
[ERR XTSE3460] It is a static error if an
xsl:apply-imports
element appears in a template rule declared within an
xsl:override
element. (To invoke the template rule
that is being overridden, xsl:next-match
should
therefore be used.)
The xsl:next-match
instruction considers as candidates all
those template rules that come after the current template rule in the
ordering of template rules implied by the conflict resolution rules given in
6.4 Conflict Resolution for Template Rules. That is, it considers all template rules with
lower import precedence than the
current template rule,
plus the template rules that are at the same import precedence that have lower
priority than the current template rule, plus
the template rules with the same import precedence and priority
that occur before the current template rule in declaration order.
Note:
As explained in 6.4 Conflict Resolution for Template Rules, a template rule with no priority
attribute, whose match pattern contains multiple alternatives
separated by |
, is treated equivalently to a set of template
rules, one for each alternative. This means that where the same item matches more than one alternative, it is possible for an xsl:next-match
instruction to cause the current template rule to be invoked recursively.
This situation does not occur when the template rule has an explicit priority.
Note:
Because a template rule declared as a child of xsl:override
has higher precedence than any template rule declared in the used package
(see 3.5.4 Overriding Template Rules from a Used Package), the effect of
xsl:next-match
within such a template rule is to
consider as candidates first any other template rules for the same mode within the
same xsl:use-package
element (taking into account explicit and implicit
priority, and document order, in the usual way), and then all template rules in
the used package.
If a matching template rule R is found, then the result
of the xsl:next-match
or xsl:apply-imports
instruction is the
result of invoking R, with the values of parameters being set using the child
xsl:with-param
elements as described in 9.10 Setting Parameter Values.
The template rule R is evaluated with the same focus as the xsl:next-match
or xsl:apply-imports
instruction. The current template rule
changes to be R. The current mode does not change.
Note:
In the case where the current template rule T is
declared within an xsl:override
element in a using package P, while
the selected rule R is declared within a different package Q, and where
the current mode is MP (mode M in package P), the effect
is that the current mode for evaluation of R
remains MP rather than reverting to its corresponding mode MQ
(mode M in package Q).
If R contains an xsl:apply-templates
instruction that uses
mode="#current"
, then the set of template rules considered by this instruction
will therefore include any overriding template rules declared in P as well as the original
rules declared in Q.
If no matching template rule is found that satisfies these criteria, the built-in template rule for the context item is used (see 6.7 Built-in Template Rules).
An xsl:apply-imports
or xsl:next-match
instruction
may use xsl:with-param
child elements to pass parameters to the
chosen template rule (see 9.10 Setting Parameter Values). It also passes on any tunnel parameters as described in 10.1.3 Tunnel Parameters.
[ERR XTDE0560] It is a dynamic error if
xsl:apply-imports
or xsl:next-match
is
evaluated when the current template
rule is absent.
xsl:apply-imports
For example, suppose the stylesheet doc.xsl
contains a template rule for example
elements:
<xsl:template match="example"> <pre><xsl:apply-templates/></pre> </xsl:template>
Another stylesheet could import doc.xsl
and modify the treatment of
example
elements as follows:
<xsl:import href="doc.xsl"/> <xsl:template match="example"> <div style="border: solid red"> <xsl:apply-imports/> </div> </xsl:template>
The combined effect would be to transform an example
into an element
of the form:
<div style="border: solid red"><pre>...</pre></div>
An xsl:fallback
instruction appearing as a child of an
xsl:next-match
instruction is ignored by an XSLT 2.0 or 3.0 processor, but can be used to define fallback
behavior when the stylesheet is processed by an XSLT 1.0 processor with forwards
compatible behavior.
A template rule may have parameters. The parameters are declared in the body of the
template using xsl:param
elements, as described in 9.2 Parameters.
Values for these parameters may be supplied in the calling
xsl:apply-templates
, xsl:apply-imports
, or
xsl:next-match
instruction by means of
xsl:with-param
elements appearing as children of the calling
instruction. The expanded QName
represented by the name
attribute of the xsl:with-param
element must match the expanded QName
represented by the name
attribute of the corresponding
xsl:param
element.
It is not an error for these instructions to supply a parameter that does not match any parameter declared in the template rule that is invoked; unneeded parameter values are simply ignored.
A parameter may be declared as a tunnel
parameter by specifying tunnel="yes"
in the
xsl:param
declaration; in this case the caller must supply the
value as a tunnel parameter by specifying tunnel="yes"
in the
corresponding xsl:with-param
element. Tunnel parameters differ from
ordinary template parameters in that they are passed transparently through multiple
template invocations. They are fully described in 10.1.3 Tunnel Parameters.