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).
[Definition: The following constructs are classified as invocation constructs: the
instructions xsl:call-template
,
xsl:apply-templates
, xsl:apply-imports
, and
xsl:next-match
; XPath function calls that bind to stylesheet functions; XPath dynamic
function calls; the functions accumulator-before
and
accumulator-after
; the [xsl:]use-attribute-sets
attribute. These all have the characteristic that they can cause evaluation of
constructs that are not lexically contained within the calling
construct.]
<!-- 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.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 package 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 3.5.3.5 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.
The target template
for an xsl:call-template
instruction is established using the
binding rules described in 3.5.3.5 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.7 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.)
The xsl:context-item
element is used as a child of
xsl:template
, to declare the required type of the context
item. It is intended particularly for use when the containing template is called
using an xsl:call-template
instruction, but it also constrains
the context item if the same template is invoked using
xsl:apply-templates
, xsl:apply-imports
, or
xsl:next-match
.
<xsl:context-item
as? = item-type
use? = "required" | "optional" | "absent" />
If the as
attribute is present then its value must be an ItemTypeXP30. If the attribute is
omitted this is equivalent to specifying as="item()"
.
[ERR XTSE3088] It is a static error if the as
attribute is
present when use="absent"
is specified.
A type error is signaled if the supplied
context item does not match its required type. No attempt is made to convert the
context item to the required type (using the function conversion rules or
otherwise). The error code is the same as for xsl:param
:
[see ERR XTTE0590].
If an xsl:context-item
element is present as
the first child element of xsl:template
, it defines whether the
template requires a context item to be supplied, and if so, what the type of the
context item must be. If this template is the initial named template, then this has the effect of placing
constraints on the global context
item for the transformation as a whole.
The use
attribute of
xsl:context-item
takes the value required
,
optional
, or absent
.
The default is
optional
.
If the containing xsl:template
element has no name
attribute then the only permitted value is required
.
If the value required
is specified, then there must be a
context item. (This will automatically be the case if the template is
invoked using xsl:apply-templates
,
xsl:apply-imports
, or xsl:next-match
,
but not if it is invoked using xsl:call-template
.)
If the value optional
is specified, or if the attribute is
omitted, or if the xsl:context-item
element is omitted,
then there may or may not be a context item when the template is
invoked.
If the value absent
is specified, then the contained sequence
constructor, and any xsl:param
elements, are evaluated with
an absent focus.
Note:
It is not an error to call such a template with a non-absent focus; the
context item is simply treated as absent. This option is useful when
streaming, since an xsl:call-template
instruction may
become streamable if the referenced template is declared to make no use
of the context item.
The processor may
signal a type error statically if the
required context item type is incompatible with the match
pattern,
that is, if no item that satisfies the match pattern can also satisfy the required
context item type.
The xsl:context-item
element plays no part in
deciding whether and when the template rule is invoked in response to an
xsl:apply-templates
instruction.
[ERR XTTE3090] It is a type error if the
xsl:context-item
child of xsl:template
specifies that a context item is required and none is supplied by the
caller, that is, if the context item is absent at the point where
xsl:call-template
is evaluated.
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.3 Tunnel Parameters.
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 the dynamically scoped variables found in some functional programming languages (for example, early versions of LISP), where evaluating a variable reference involves searching down the dynamic call stack for a matching variable name. There are two main use cases for the feature:
They provide a way to supply context information that might be needed by many
templates (for example, the fact that the output is to be localized for a particular
language),
but which cannot be placed in a global variable because it might vary from one phase
of processing
to another. Passing such information using conventional parameters is error-prone,
because
a single xsl:apply-templates
or xsl:call-template
instruction
that neglects to pass the information on will lead to failures that are difficult
to diagnose.
They are particularly useful when writing a customization layer for an existing stylesheet. For example, if you want to override a template rule that displays chemical formulae, you might want the new rule to be parameterized so you can apply the house-style of a particular scientific journal. Tunnel parameters allow you to pass this information to the overriding template rule without requiring modifications to all the intermediate template rules. Again, a global variable could be used, but only if the same house-style is to be used for all chemical formulae processed during a single transformation.
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.
Tunnel parameters are passed unchanged through a built-in template rule (see 6.7 Built-in Template Rules).
If a tunnel parameter is declared in an
xsl:param
element with the attribute
tunnel="yes"
, and if the
parameter is explicitly
or implicitly mandatory,
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? = boolean >
<!-- 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.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.1 Qualified Names.
[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 an
EQName that does not match the name
attribute of any
xsl:attribute-set
declaration in the containing package.
An attribute set may be considered
as comprising a sequence of instructions, each of which is either an
xsl:attribute
instruction or an attribute set invocation. Starting with the declarations making up
an attribute set, this sequence of instructions can be generated by the following
rules:
The relevant attribute set declarations (that is, all declarations of attribute sets within a package sharing the same expanded QName) are considered in order: first in increasing order of import precedence, and within each precedence, in declaration order.
Each declaration is expanded to a sequence of instructions as follows.
First, one attribute set invocation is generated for
each EQName present in the use-attribute-sets
attribute, if
present, retaining the order in which the EQNames appear. This is followed
by the sequence of contained xsl:attribute
instructions, in
order.
[Definition: An
attribute set invocation is a pseudo-instruction
corresponding to a single EQName appearing within an
[xsl:]use-attribute-sets
attribute; the effect of the
pseudo-instruction is to cause the referenced attribute set to be evaluated.]
Similarly, an [xsl:]use-attribute-sets
attribute of an xsl:copy
, xsl:element
, or
xsl:attribute-set
element, or of a literal result element, is
expanded to a sequence of attribute set
invocations, one for each EQName in order.
An attribute set is a named component, and the binding of QNames appearing in an attribute set invocation to attribute set components follows the rules in 3.5.3.5 Binding References to Components.
The following two (mutually recursive) rules define how
an [xsl:]use-attribute-set
attribute is expanded:
An attribute set is evaluated by evaluating each of the
contained attribute set
invocations and xsl:attribute
instructions in
order, to deliver a sequence of attribute nodes.
An attribute set invocation is evaluated by evaluating the attribute set to which it is bound, as determined by the rules in 3.5.3.5 Binding References to Components.
For rules regarding cycles in attribute set declarations, see 9.11 Circular Definitions.
Note:
The effect of an attribute set invocation on the dynamic
context is the same as the effect of an xsl:call-template
instruction. In particular, it does not change the focus.
Although attribute sets are often defined with fixed values, or with values
that depend only on global variables, it is possible to define an attribute set
in such a way that the values of the constructed attributes are dependent on
the context item.
Note:
In all cases the result of evaluating an attribute set is subsequently used to create the attributes of an element node, using the rules in 5.7.1 Constructing Complex Content. The effect of those rules is that when the result of evaluating the attribute set contains attributes with duplicate names, the last duplicate wins. The optimization rules allow a processor to avoid evaluating or validating an attribute if it is able to determine that the attribute will subsequently be discarded as a duplicate.
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 all the following conditions are satisfied:
Every xsl:attribute-set
declaration for the attribute set has the attribute
streamable="yes"
.
Every xsl:attribute-set
declaration for the attribute set
is grounded and motionless according to the analysis in 19.8.6 Classifying Attribute Sets.
Specifying streamable="yes"
on an
xsl:attribute-set
element declares an intent that the
attribute set 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 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.
[ERR XTSE0730] If an xsl:attribute
set element specifies
streamable="yes"
then every attribute set referenced in its
use-attribute-sets
attribute (if present) must also specify
streamable="yes"
.
Note:
It is common for attribute sets to create attributes with constant values, and
such attribute sets will always be grounded and 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 a 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
sequence constructor contained by 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.
Note:
The above rule means that for an xsl:copy
element with a select
attribute, the focus for evaluating any referenced attribute
sets is the node selected by the select
attribute, rather than the context item of
the xsl:copy
instruction.
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
(subject to visibility
rules).]
<!-- Category: declaration -->
<xsl:function
name = eqname
as? = sequence-type
visibility? = "public" | "private" | "final" | "abstract"
streamability? = "unclassified" | "absorbing" | "inspection" | "filter" | "shallow-descent"
| "deep-descent" | "ascent" | eqname
override-extension-function? = boolean
[override]? = boolean
new-each-time? = "yes" | "true" | "1" | "no" | "false" | "0" | "maybe"
cache? = boolean >
<!-- 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.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.
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 parameters 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.
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.
[ERR XTSE0760] It is a static error if an xsl:param
child of
an xsl:function
element has either a select
attribute or non-empty content.
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, and the
errors that can occur, 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
.
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. (See [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
SequenceType.
[ERR XTTE0780] If the as
attribute is specified, then the result evaluated by the sequence constructor (see
5.7 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.
The XPath specification states that 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. In XSLT 3.0, final determination of the function to be called cannot be made until all packages have been assembled: see 3.5.3.5 Binding References to Components.
An xsl:function
declaration defines a stylesheet function which forms a
component in its 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.5 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 xsl:function
declarations with the same expanded QName, the same arity, and the same import
precedence, unless there is another xsl:function
declaration 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.
The streamability
attribute of xsl:function
is used
to assign the function to one of a number of streamability categories. The various
categories, and their effect on the streamability of function calls, are described
in 19.8.5 Classifying Stylesheet Functions.
The streamability category of a function characterizes the way in which the
function processes any streamed nodes supplied in the first argument to the
function. (In general, streamed nodes cannot be supplied in other arguments,
unless they are atomized by the function conversion rules.)
The streamability
attribute is therefore not applicable unless the
function takes at least one argument.
[ERR XTSE3155] It is a static error if an xsl:function
element with no
xsl:param
children has a streamability
attribute with any value other than unclassified
.
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 nondeterministic, 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 subexpressions.
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.
Three classes of functions can be identified:
DeterministicFO31
functions: as the term is defined in [Functions and Operators 3.1],
these offer a guarantee that when a function is called repeatedly with the
same arguments, it returns the same results. A classic example is the
doc
FO30 function, which offers the guarantee that
doc($X) is doc($X)
: that is, two calls supplying the same
URI return the same node.
Proactive functions: these offer the guarantee that each invocation of the function causes a single execution of the function body, or behaves exactly as if it did so. In particular this means that when the function creates new nodes, it creates new nodes on each invocation. By default, stylesheet functions are proactive.
Elidable functions: these offer no guarantee of determinism, and no
guarantee of proactive evaluation. If the function creates new nodes, then
two calls on the function with the same arguments may or may not return the
same nodes, at the implementation’s discretion. Examples of elidable functions include
the [Functions and Operators 3.1] functions
analyze-string
FO30 and
json-to-xml
.
The new-each-time
attribute of xsl:function
allows a
stylesheet function to be assigned to one of these three categories. The value
new-each-time="no"
means the function is deterministic; the value
new-each-time="yes"
means it is proactive; and the value
new-each-time="maybe"
means it is elidable.
The definition of determinismFO31 requires a definition of what it means for a function to be called twice with “the same” arguments and to return “the same” result. This is defined in [Functions and Operators 3.1], specifically by the definition of the term identicalFO31.
Processors have considerable freedom to optimize execution of stylesheets, and of
function calls in particular, but the strategies that are adopted must respect the
specification as to whether functions are deterministic, proactive, or elidable.
For example, consider a function call that appears within an
xsl:for-each
instruction, where the supplied arguments to the
function do not depend on the context item or on any variables declared within the
xsl:for-each
instruction. A possible optimization is to
execute the function call only once, rather than executing it repeatedly each time
round the loop (this is sometimes called loop-lifting). This optimization is safe
when the function is deterministic or elidable, but it requires great care if the
function is proactive; it is permitted only if the processor is able to determine
that the results of stylesheet execution are equivalent to the results that would
be obtained if the optimization had not been performed. Declaring a function call
to be elidable (by writing new-each-time="maybe"
) makes it more
likely that an implementation will be able to apply this optimization, as well as
other optimizations such as caching or memoization.
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="yes"
encourages the processor to retain memory of
previous calls of this function
during the same transformation and to reuse results from this memory whenever
possible. The default value cache="no"
encourages the
processor not to retain memory of previous calls.
In all cases the results must respect the semantics. If a function is proactive
(new-each-time="yes"
) then caching of results may be infeasible,
especially if the function result can include nodes; but it is not an error to
request it, since some implementations may be able to provide caching, or
analogous optimizations, even for proactive functions. (One possible strategy is
to return a copy of the cached result, thus creating the illusion that the
function has been evaluated anew.)
Note:
Memoization is essentially a trade-off between time and space; a memoized function can be expected to use more memory to deliver faster execution. Achieving an optimum balance may require configuring the size of the cache that is used; implementations may use additional extension attributes or other mechanisms to provide finer control of this kind.
Note:
Memoization of a function generally involves creating an associative table (for
example, a hash map) that maps argument values to function results. To get this
right, it is vital that the key for this table should correctly reflect what it
means for two function calls to have “the same arguments”. Does it matter, for
example, that one call passes the xs:string
value "Paris", while
another passes the xs:untypedAtomic
value "Paris"? If the function
is declared with new-each-time="maybe"
, then the rules say that
these cannot be treated as “the same arguments”: the definition of identicalFO31 requires them to have exactly the same type
as well as being equal. However, an implementation that is able to determine
that all references to the argument within the function body only make use of
its string value might be able to take advantage of this fact, and thus perform
more efficient caching.
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 arguments 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? = { boolean } >
<!-- 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 expression (that is, if a static error occurs when analyzing the string according to the rules of the XPath 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 Maps for details of
maps).
[ERR XTTE3165] It is a type error if the
result of evaluating the expression in the with-params
attribute of the xsl:evaluate
instruction is
anything other than a single map of type
map(xs:QName, item()*)
.
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.14 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.
If a variable name is present both the static
xsl:with-param
children and also in the dynamic
with-params
map, the value from the latter takes
precedence.
Note:
Variables declared in the stylesheet in xsl:variable
or
xsl:param
elements are not in-scope
within the target expression.
Function signatures:
All functions defined in [Functions and Operators 3.0] in the
fn
and math
namespaces;
All functions in the fn
and map
namespaces whose definitions
appear both in this specification and also in [Functions and Operators 3.1];
If the processor supports XPath 3.1, all functions defined in [Functions and Operators 3.1]
in the fn
, math
, map
, and array
namespaces;
Constructor functions for named simple types included in the in-scope schema definitions;
All user-defined functions present in the containing package provided their visibility
is
not hidden
or private
;
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.2 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.3.4 Additional Dynamic Context Components used by XSLT are all absent.
The named functionsXP30
(representing the functions accessible using function-available
or function-lookup
FO30)
include all the functions available in the static context, and may also include an
additional
implementation-defined set of functions that are available dynamically but not statically.
All other aspects of the dynamic context are the same as the dynamic context
for the xsl:evaluate
instruction itself, except that an implementation may
restrict
the availability of external resources (for example, available documents)
or provide options to restrict their availability, for security
reasons.
Note:
For example, a processor may disallow access using the
doc
FO30 or collection
FO30 functions
to documents in local filestore.
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 27.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 the string "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 the string "yes"
;
A call to system-property('xsl:supports-dynamic-evaluation')
appearing anywhere else returns the string "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
.
If a processor supports the dynamic evaluation feature, it is implementation-defined how the processor allows users to disable dynamic evaluation and it is implementation-defined whether the mechanism is static or dynamic.
[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 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.
If the function-lookup
FO30 function were not available
in the standard library, then a very similar function 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:try> <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:catch errors="err:XTDE3160" select="()"/> </xsl:try> </xsl:function>
Note:
The main difference between this function and the standard function-lookup
FO30
function is that there are differences in the functions that are visible: for example
function-lookup
FO30
gives access to user-defined functions with private visibility, whereas xsl:evaluate
does not.
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.