1 Introduction
1.1 What is XSLT?
This specification defines the syntax and semantics of the XSLT 3.0 language.
A transformation in the XSLT language is expressed in the form of a stylesheet. A stylesheet is made up of one or more well-formed XML [XML 1.0] documents conforming to the Namespaces in XML Recommendation [Namespaces in XML].
A stylesheet generally includes elements that are defined by XSLT as well as elements
that are not defined by XSLT. XSLT-defined elements are distinguished by use of the
namespace http://www.w3.org/1999/XSL/Transform (see 3.1 XSLT Namespace), which is referred to in this specification as the
XSLT namespace. Thus this specification
is a definition of the syntax and semantics of the XSLT namespace.
The term stylesheet reflects the fact that one of the important roles of XSLT is to add styling information to an XML source document, by transforming it into a document consisting of XSL formatting objects (see [XSL-FO]), or into another presentation-oriented format such as HTML, XHTML, or SVG. However, XSLT is used for a wide range of transformation tasks, not exclusively for formatting and presentation applications.
A transformation expressed in XSLT describes rules for transforming input data into output data. The inputs and outputs will all be instances of the XDM data model, described in [XDM 3.0]. In the simplest and most common case, the input is an XML document referred to as the source tree, and the output is an XML document referred to as the result tree. It is also possible to process multiple source documents, to generate multiple result documents, and to handle formats other than XML. The transformation is achieved by a set of template rules. A template rule associates a pattern, which typically matches nodes in the source document, with a sequence constructor. In many cases, evaluating the sequence constructor will cause new nodes to be constructed, which can be used to produce part of a result tree. The structure of the result trees can be completely different from the structure of the source trees. In constructing a result tree, nodes from the source trees can be filtered and reordered, and arbitrary structure can be added. This mechanism allows a stylesheet to be applicable to a wide class of documents that have similar source tree structures.
Stylesheets have a modular structure; they may contain several packages developed independently of each other, and each package may consist of several stylesheet modules.
[Definition: A stylesheet consists of one or more packages: specifically, one top-level package and zero or more library packages.]
[Definition: For a given transformation, one package functions as the top-level package. The
complete stylesheet is assembled by finding
the packages referenced directly or indirectly from the top-level package using
xsl:use-package declarations: see 3.5.2 Dependencies between Packages.]
[Definition: Every package within a stylesheet, other than the top-level package, is referred to as a library package.]
[Definition: Within a package, one stylesheet module functions as the
principal stylesheet module. The complete package is assembled by
finding the stylesheet modules referenced directly or indirectly from the
principal stylesheet module using xsl:include and
xsl:import elements: see 3.11.2 Stylesheet Inclusion and 3.11.3 Stylesheet Import.]
1.2 What’s New in XSLT 3.0?
A major focus for enhancements in XSLT 3.0 is the requirement to enable streaming of source documents. This is needed when source documents become too large to hold in main memory, and also for applications where it is important to start delivering results before the entire source document is available.
While implementations of XSLT that use streaming have always been theoretically possible, the nature of the language has made it very difficult to achieve this in practice. The approach adopted in this specification is twofold: it identifies a set of restrictions which, if followed by stylesheet authors, will enable implementations to adopt a streaming mode of operation without placing excessive demands on the optimization capabilities of the processor; and it provides new constructs to indicate that streaming is required, or to express transformations in a way that makes it easier for the processor to adopt a streaming execution plan.
Capabilities provided in this category include:
-
A new
xsl:source-documentinstruction, which reads and processes a source document, optionally in streaming mode; -
The ability to declare that a mode is a streaming mode, in which case all the template rules using that mode must be streamable;
-
A new
xsl:iterateinstruction, which iterates over the items in a sequence, allowing parameters for the processing of one item to be set during the processing of the previous item; -
A new
xsl:mergeinstruction, allowing multiple input streams to be merged into a single output stream; -
A new
xsl:forkinstruction, allowing multiple computations to be performed in parallel during a single pass through an input document; -
Accumulators, which allow a value to be computed progressively during streamed processing of a document, and accessed as a function of a node in the document, without compromise to the functional nature of the XSLT language.
A second focus for enhancements in XSLT 3.0 is the introduction of a new mechanism for stylesheet modularity, called the package. Unlike the stylesheet modules of XSLT 1.0 and 2.0 (which remain available), a package defines an interface that regulates which functions, variables, templates and other components are visible outside the package, and which can be overridden. There are two main goals for this facility: it is designed to deliver software engineering benefits by improving the reusability and maintainability of code, and it is intended to streamline stylesheet deployment by allowing packages to be compiled independently of each other, and compiled instances of packages to be shared between multiple applications.
Other significant features in XSLT 3.0 include:
-
An
xsl:evaluateinstruction allowing evaluation of XPath expressions that are dynamically constructed as strings, or that are read from a source document; -
Enhancements to the syntax of patterns, in particular enabling the matching of atomic values as well as nodes;
-
An
xsl:tryinstruction to allow recovery from dynamic errors; -
The element
xsl:global-context-item, used to declare the stylesheet’s expectations of the global context item (notably, its type); -
A new instruction
xsl:assertto assist developers in producing correct and robust code.
XSLT 3.0 also delivers enhancements made to the XPath language and to the standard function library, including the following:
-
Variables can now be bound in XPath using the
letexpression. -
Functions are now first class values, and can be passed as arguments to other (higher-order) functions, making XSLT a fully-fledged functional programming language.
-
A number of new functions are available, for example trigonometric functions, and the functions
parse-xmlFO30 andserializeFO30 to convert between lexical and tree representations of XML.
XSLT 3.0 also includes support for maps (a data structure consisting of key/value pairs, sometimes referred to in other programming languages as dictionaries, hashes, or associative arrays). This feature extends the data model, provides new syntax in XPath, and adds a number of new functions and operators. Initially developed as XSLT-specific extensions, maps have now been integrated into XPath 3.1 (see [XPath 3.1]). XSLT 3.0 does not require implementations to support XPath 3.1 in its entirety, but it does requires support for these specific features.
A full list of changes is at J Changes since XSLT 2.0.
2 Concepts
2.1 Terminology
For a full glossary of terms, see C Glossary.
[Definition: The software responsible for transforming source trees into result trees using an XSLT stylesheet is referred to as the processor. This is sometimes expanded to XSLT processor to avoid any confusion with other processors, for example an XML processor.]
[Definition: A specific product that performs the functions of an XSLT processor is referred to as an implementation.]
[Definition: The term tree is used (as in [XDM 3.0]) to refer to the aggregate consisting of a parentless node together with all its descendant nodes, plus all their attributes and namespaces.]
Note:
The use of the term tree in this document does not imply the use of a data structure in memory that holds the entire contents of the document at one time. It implies rather a logical view of the XML input and output in which elements have a hierarchic relationship to each other. When a source document is being processed in a streaming manner, access to the nodes in this tree is constrained, but it is still viewed and described as a tree.
The output of a transformation consists of the following:
-
[Definition: A principal result: this can be any sequence of items (as defined in [XDM 3.0]).] The principal result is the value returned by the function or template in the stylesheet that is nominated as the entry point, as described in 2.3 Initiating a Transformation.
-
[Definition: Zero or more secondary results: each secondary result can be any sequence of items (as defined in [XDM 3.0]).] A secondary result is the value returned by evaluating the body of an
xsl:result-documentinstruction. -
Zero or more messages. Messages are generated by the
xsl:messageandxsl:assertinstructions, and are described in 23.1 Messages and 23.2 Assertions. -
Static or dynamic errors: see 2.14 Error Handling.
The principal result and the secondary results may be post-processed as described in 2.3.6 Post-processing the Raw Result.
[Definition: The term result tree is used to refer to any tree constructed by instructions in the stylesheet. A result tree is either a final result tree or a temporary tree.]
[Definition: A final result tree is a result tree that forms part of the output of a transformation: specifically, a tree built by post-processing the items in the principal result or in a secondary result. Once created, the contents of a final result tree are not accessible within the stylesheet itself.] Any final result tree may be serialized as described in 26 Serialization.
[Definition: The term source tree
means any tree provided as input to the transformation. This includes the document
containing the global context item if any, documents containing
nodes present in the initial match selection,
documents containing nodes supplied as the values of stylesheet parameters, documents
obtained from the results of functions such as document,
docFO30, and collectionFO30, documents read using the xsl:source-document
instruction, and documents returned by extension functions or
extension instructions. In the context of a particular XSLT instruction, the term
source tree means any tree provided as input to that instruction;
this may be a source tree of the transformation as a whole, or it may be a
temporary tree produced during the
course of the transformation.]
[Definition: The term temporary tree means any tree that is neither a source tree nor a final result tree.] Temporary trees are used to hold intermediate results during the execution of the transformation.
The use of the term “tree” in phrases such as source tree, result tree, and temporary tree is not confined to documents that the processor materializes in memory in their entirety. The processor may, and in some cases must, use streaming techniques to limit the amount of memory used to hold source and result documents. When streaming is used, the nodes of the tree may never all be in memory at the same time, but at an abstract level the information is still modeled as a tree of nodes, and the document is therefore still described as a tree. Unless otherwise stated, the term “tree” refers to a tree rooted at a parentless node: that is, the term does not include subtrees of larger trees. Every node therefore belongs to exactly one tree.
In this specification the phrases must, must not, should, should not, may, required, and recommended, when used in normative text and rendered in capitals, are to be interpreted as described in [RFC2119].
Where the phrase must, must not, or required relates to the behavior of the XSLT processor, then an implementation is not conformant unless it behaves as specified, subject to the more detailed rules in 27 Conformance.
Where the phrase must, must not, or required relates to a stylesheet then the processor must enforce this constraint on stylesheets by reporting an error if the constraint is not satisfied.
Where the phrase should, should not, or recommended relates to a stylesheet then a processor may produce warning messages if the constraint is not satisfied, but must not treat this as an error.
[Definition: In this specification, the term implementation-defined refers to a feature where the implementation is allowed some flexibility, and where the choices made by the implementation must be described in documentation that accompanies any conformance claim.]
[Definition: The term implementation-dependent refers to a feature where the behavior may vary from one implementation to another, and where the vendor is not expected to provide a full specification of the behavior.] (This might apply, for example, to limits on the size of source documents that can be transformed.)
In all cases where this specification leaves the behavior implementation-defined or implementation-dependent, the implementation has the option of providing mechanisms that allow the user to influence the behavior.
A paragraph labeled as a Note or described as an example is non-normative.
Many terms used in this document are defined in the XPath specification [XPath 3.0] or the XDM specification [XDM 3.0]. Particular attention is drawn to the following:
-
[Definition: The term atomization is defined in Section 2.4.2 Atomization XP30. It is a process that takes as input a sequence of items, and returns a sequence of atomic values, in which the nodes are replaced by their typed values as defined in [XDM 3.0]. If the XPath 3.1 Feature is implemented, then arrays (see 27.7.1 Arrays) are atomized by atomizing their members, recursively.] For some items (for example, elements with element-only content, function items, and maps), atomization generates a dynamic error.
-
[Definition: The term typed value is defined in Section 5.15 typed-value Accessor DM30. Every node, other than an element whose type annotation identifies it as having element-only content, has a typed value. For example, the typed value of an attribute of type
xs:IDREFSis a sequence of zero or morexs:IDREFvalues.] -
[Definition: The term string value is defined in Section 5.13 string-value Accessor DM30. Every node has a string value. For example, the string value of an element is the concatenation of the string values of all its descendant text nodes.]
-
[Definition: The term XPath 1.0 compatibility mode is defined in Section 2.1.1 Static Context XP30. This is a setting in the static context of an XPath expression; it has two values,
trueandfalse. When the value is set to true, the semantics of function calls and certain other operations are adjusted to give a greater degree of backwards compatibility between XPath 3.0 and XPath 1.0.]
2.2 Notation
[Definition: An XSLT element is an element in the XSLT namespace whose syntax and semantics are defined in this specification.] For a non-normative list of XSLT elements, see D Element Syntax Summary.
In this document the specification of each XSLT element is preceded by a summary of its syntax in the form of a model for elements of that element type. A full list of all these specifications can be found in D Element Syntax Summary. The meaning of the syntax summary notation is as follows:
-
An attribute that is required is shown with its name in bold. An attribute that may be omitted is shown with a question mark following its name.
-
An attribute that is deprecated is shown in a grayed font within square brackets.
-
The string that occurs in the place of an attribute value specifies the allowed values of the attribute. If this is surrounded by curly brackets (
{...}), then the attribute value is treated as an attribute value template, and the string occurring within curly brackets specifies the allowed values of the result of evaluating the attribute value template. Alternative allowed values are separated by|. A quoted string indicates a value equal to that specific string. An unquoted, italicized name specifies a particular type of value.The types used, and their meanings, are as follows:
-
boolean -
One of the strings
"yes","true", or"1"to indicate the valuetrue, or one of the strings"no","false", or"0"to indicate the valuefalse. Note: the values are synonyms; where this specification uses a phrase such as “Ifrequired='yes'is specified ...” this is to be interpreted as meaning “If the attribute namedrequiredis present, and has the valueyes,true, or1(after stripping leading and trailing whitespace) ...”. string-
Any string
expression-
An XPath expression
pattern-
A pattern as described in 5.5 Patterns.
item-type-
An ItemTypeXP30 as defined in the XPath 3.0 specification (or in XPath 3.1 if the processor implements the XPath 3.1 Feature)
sequence-type-
A SequenceTypeXP30 as defined in the XPath 3.0 specification (or in XPath 3.1 if the processor implements the XPath 3.1 Feature)
uri; uris-
A URI, for example a namespace URI or a collation URI; a whitespace-separated list of URIs
qname-
A lexical QName as defined in 5.1.1 Qualified Names
eqname; eqnames-
An EQName as defined in 5.1.1 Qualified Names; a whitespace-separated list of EQNames
token; tokens-
A string containing no significant whitespace; a whitespace-separated list of such strings
nmtoken; nmtokens-
A string conforming to the XML schema rules for the type
xs:NMTOKEN; a whitespace-separated list of such strings. char-
A string comprising a single Unicode character
integer-
An integer, that is a string in the lexical space of the schema type
xs:integer decimal-
A decimal value, that is a string in the lexical space of the schema type
xs:decimal ncname-
An unprefixed name: a string in the value space of the schema type
xs:NCName prefix-
An
xs:NCNamerepresenting a namespace prefix, which must be in scope for the element on which it appears id-
An
xs:NCNameused as a unique identifier for an element in the containing XML document
Except where the set of allowed values of an attribute is specified using the italicized name string or char, leading and trailing whitespace in the attribute value is ignored. In the case of an attribute value template, this applies to the effective value obtained when the attribute value template is expanded.
XPath comments (delimited by
(: ... :)) are permitted anywhere that inter-token whitespace is permitted in attributes whose type is given as expression, pattern, item-type, or sequence-type, and are not permitted in attributes of other types (other than within expressions enclosed by curly braces within an attribute value template). -
-
Unless the element is required to be empty, the model element contains a comment specifying the allowed content. The allowed content is specified in a similar way to an element type declaration in XML; sequence constructor means that any mixture of text nodes, literal result elements, extension instructions, and XSLT elements from the instruction category is allowed; other-declarations means that any mixture of XSLT elements from the declaration category is allowed, together with user-defined data elements.
-
The element is prefaced by comments indicating if it belongs to the
instructioncategory ordeclarationcategory or both. The category of an element only affects whether it is allowed in the content of elements that allow a sequence constructor or other-declarations.
This example illustrates the notation used to describe XSLT elements.
<!-- Category: instruction -->
<xsl:example-element
select = expression
debug? = boolean
validation? = { "strict" | "lax" } >
<!-- Content: ((xsl:variable | xsl:param)*, xsl:sequence) -->
</xsl:example-element>
This example defines a (non-existent) element xsl:example-element.
The element is classified as an instruction. It takes the following
attributes:
-
A mandatory
selectattribute, whose value is an XPath expression -
An optional
debugattribute, whose value must beyes,true, or1to indicatetrue, orno,false, or0to indicatefalse. -
An optional
validationattribute, whose value must bestrictorlax; the curly brackets indicate that the value can be defined as an attribute value template, allowing a value such asvalidation="{$val}", where the variablevalis evaluated to yield"strict"or"lax"at run-time.
The content of an xsl:example-element instruction is defined to be a
sequence of zero or more xsl:variable and
xsl:param elements, followed by an
xsl:sequence element.
[ERR XTSE0010] It is a static error if an XSLT-defined element is used in a context where it is not permitted, if a required attribute is omitted, or if the content of the element does not correspond to the content that is allowed for the element.
The rules in the element syntax summary (both for the element structure and for its attributes) apply to the stylesheet content after preprocessing as described in 3.13 Stylesheet Preprocessing.
Attributes are validated as follows. These rules apply to the value of the attribute after removing leading and trailing whitespace.
-
[ERR XTSE0020] It is a static error if an attribute (other than an attribute written using curly brackets in a position where an attribute value template is permitted) contains a value that is not one of the permitted values for that attribute.
-
[ERR XTDE0030] It is a dynamic error if the effective value of an attribute written using curly brackets, in a position where an attribute value template is permitted, is a value that is not one of the permitted values for that attribute. If the processor is able to detect the error statically (for example, when any XPath expressions within the curly brackets can be evaluated statically), then the processor may optionally signal this as a static error.
Special rules apply if the construct appears in part of the stylesheet that is processed with forwards compatible behavior: see 3.10 Forwards Compatible Processing.
[Definition: Some constructs defined in this specification are described as being deprecated. The use of this term implies that stylesheet authors should not use the construct, and that the construct may be removed in a later version of this specification.]
Note:
This specification includes a non-normative XML Schema for XSLT stylesheet modules (see H Schemas for XSLT 3.0 Stylesheets). The syntax summaries described in this section are normative.
XSLT defines a set of standard functions which are additional to those defined in [Functions and Operators 3.0]. A list of these functions appears in G.2 List of XSLT-defined functions. The signatures of these functions are described using the same notation as used in [Functions and Operators 3.0]. The names of many of these functions are in the standard function namespace.
2.3 Initiating a Transformation
This document does not specify any application programming interfaces or other interfaces for initiating a transformation. This section, however, describes the information that is supplied when a transformation is initiated. Except where otherwise indicated, the information is required.
The execution of a stylesheet necessarily involves two activities: static analysis
and dynamic evaluation. Static analysis consists of those tasks that can be performed
by inspection of the stylesheet alone, including the
binding of static variables,
the evaluation of [xsl:]use-when expressions (see 3.13.1 Conditional Element Inclusion), and shadow attributes
(see 3.13.2 Shadow Attributes) and detection of static errors. Dynamic evaluation consists of
tasks which in general cannot be carried out until a source document is
available.
Dynamic evaluation is further divided into two activities: priming the stylesheet, and invoking a selected component.
-
Priming the stylesheet provides the dynamic context for evaluation, and supplies all the information needed to establish the values of global variables.
-
Invoking a component (such as a template or function) causes evaluation of that template or function to produce a result, which is an arbitrary XDM value.
[Definition: The result of invoking the selected component, after any required conversion to the declared result type of the component, is referred to as the raw result.]
The raw result of the invocation is the immediate result of evaluating the sequence constructor contained in the target template or function, modified by applying the function conversion rules to convert the immediate result to the type declared in the
asattribute of thexsl:templateorxsl:functiondeclaration, if present.This raw result may optionally be post-processed to construct a result tree, to serialize the result, or both, as described in 2.3.6 Post-processing the Raw Result.
Implementations may allow static analysis and dynamic evaluation to be initiated independently, so that the cost of static analysis can be amortized over multiple transformations using the same stylesheet. Implementations may also allow priming of a stylesheet and invocation of components to be initiated independently, in which case a single act of priming the stylesheet may be followed by a series of independent component invocations. Although this specification does not require such a separation, this section distinguishes information that is needed before static analysis can proceed, information that is needed to prime the stylesheet, and information that is needed when invoking components.
The language is designed to allow the static analysis of each package to be performed independently of other packages, with only basic knowledge of the properties of components made available by used packages. Beyond this, the specification leaves it to implementations to decide how to organize this process. When packages are not used explicitly, the entire stylesheet is treated as a single package.
2.3.1 Information needed for Static Analysis
The following information is needed prior to static analysis of a package:
-
The location of the package manifest, or in the absence of a package manifest, the stylesheet module that is to act as the principal stylesheet module of the package. The complete package is assembled by recursively expanding the
xsl:importandxsl:includedeclarations in the principal stylesheet module, as described in 3.11.2 Stylesheet Inclusion and 3.11.3 Stylesheet Import. -
Information about the packages referenced from this package using
xsl:use-packagedeclarations. The information needed will include the names and signatures of public components exported by the referenced package. -
A set (possibly empty) of values for static parameters (see 9.5 Global Variables and Parameters). These values are available for use within static expressions (notably in
[xsl:]use-whenexpressions and shadow attributes) as well as non-static expressions in the stylesheet. As a minimum, values must be supplied for any static parameters declared with the attributerequired="yes".
Conceptually, the output of the static analysis of a package is an object which might be referred to (without constraining the implementation) as a compiled package. Prior to dynamic evaluation, all the compiled packages needed for execution must be checked for consistency, and component references must be resolved. This process may be referred to, again without constraining the implementation, as linking.
2.3.2 Priming a Stylesheet
The information needed when priming a stylesheet is as follows:
-
A set (possibly empty) of values for non-static stylesheet parameters (see 9.5 Global Variables and Parameters). These values are available for use within expressions in the stylesheet. As a minimum, values must be supplied for any parameters declared with the attribute
required="yes".A supplied value is converted if necessary to the declared type of the stylesheet parameter using the function conversion rules.
Note:
Non-static stylesheet parameters are implicitly
public, which ensures that all the parameters in the stylesheet for which values can be supplied externally have distinct names. Static parameters, by contrast, are local to a package. -
[Definition: An item that acts as the global context item for the transformation. This item acts as the context item when evaluating the
selectexpression or sequence constructor of a global variable declaration within the top-level package, as described in 5.3.3.1 Maintaining Position: the Focus. The global context item may also be available in a named template when the stylesheet is invoked as described in 2.3.4 Call-Template Invocation].Note:
In previous releases of this specification, a single node was typically supplied to represent the source document for the transformation. This node was used as the target node for the implicit call on
xsl:apply-templatesused to start the transformation process (now called the initial match selection), and the root node of the containing tree was used as the context item for evaluation of global variables (now called the global context item). This relationship between the initial match selection and the global context item is likely to be found for compatibility reasons in a transformation API designed to work with earlier versions of this specification, but it is no longer a necessary relationship; the two values can in principle be completely independent of each other.Stylesheet authors wanting to write code that can be invoked using legacy APIs should not rely on the caller being able to supply different values for the initial match selection and the global context item.
The value given to the global context item (and the values given to stylesheet parameters) cannot be nodes in a streamed document. This rule ensures that all global variables can freely navigate within the relevant tree, with no constraints imposed by the streamability rules.
The global context item is potentially used when initializing global variables and parameters. If the initialization of any global variables or parameter depends on the context item, a dynamic error can occur if the context item is absent. It is implementation-defined whether this error occurs during priming of the stylesheet or subsequently when the variable is referenced; and it is implementation-defined whether the error occurs at all if the variable or parameter is never referenced. The error can be suppressed by use of
xsl:tryandxsl:catchwithin the sequence constructor used to initialize the variable or parameter. It cannot be suppressed by use ofxsl:tryaround a reference to the global variable.In a library package, the context item, context position, and context size used for evaluation of global variables will be absent, and the evaluation of any expression that references these values will result in a dynamic error. This will also be the case in the top-level package if no global context item is supplied.
Note:
If a context item is available within a global variable declaration, then the context position and context size will always be 1 (one).
Note:
For maximum reusability of code, it is best to avoid use of the context item when initializing global variables and parameters. Instead, all external information should be supplied using named stylesheet parameters. Especially when these use namespaces to avoid conflicts, there is then no risk of confusion between the information supplied externally to different packages.
When a stylesheet parameter is defined in a library package, it is possible for a using package to supply a value for the parameter by overriding the parameter declaration within an
xsl:overrideelement. If the using package is the top-level package then the overriding declaration can refer to the global context item. -
A mechanism for obtaining a document node and a media type, given an absolute URI. The total set of available documents (modeled as a mapping from URIs to document nodes) forms part of the context for evaluating XPath expressions, specifically the
docFO30 function. The XSLTdocumentfunction additionally requires the media type of the resource representation, for use in interpreting any fragment identifier present within a URI Reference.Note:
The set of documents that are available to the stylesheet is implementation-dependent, as is the processing that is carried out to construct a tree representing the resource retrieved using a given URI. Some possible ways of constructing a document (specifically, rules for constructing a document from an Infoset or from a PSVI) are described in [XDM 3.0].
Once a stylesheet is primed, the values of global variables
remain stable through all component invocations. In addition, priming a stylesheet
creates an execution scopeFO30
during which the dynamic context and all calls
on deterministicFO30
functions remain stable; for example two calls on the
current-dateTimeFO30 function within an execution scope are
defined to return the same result.
Parameters passed to the transformation by the client application when a stylesheet is primed are matched against stylesheet parameters (see 9.5 Global Variables and Parameters), not against the template parameters of any template executed during the course of the transformation.
[ERR XTDE0050] It is a dynamic error if a stylesheet declares a visible stylesheet parameter that is explicitly or implicitly mandatory, and no value for this parameter is supplied when the stylesheet is primed. A stylesheet parameter is visible if it is not masked by another global variable or parameter with the same name and higher import precedence. If the parameter is a static parameter then the value must be supplied prior to the static analysis phase.
2.3.3 Apply-Templates Invocation
[Definition: A stylesheet may be evaluated by supplying a
value to be processed, together with an initial mode. The
value (which can be any sequence of items) is referred to as the initial
match selection. The processing then corresponds to the effect of the
xsl:apply-templates instruction.]
The initial match selection will often be a single document node, traditionally called the source document of the transformation; but in general, it can be any sequence. If the initial match selection is an empty sequence, the result of the transformation will be empty, since no template rules are evaluated.
Processing proceeds by finding the template rules that match the items in the initial match selection, and evaluating these template rules with a focus based on the initial match selection. The template rules are evaluated in final output state.
The following information is needed when dynamic evaluation is to start with a template rule:
-
The initial match selection. An API that chooses to maintain compatibility with previous versions of this specification should allow a method of invocation in which a singleton node is provided, which is then used in two ways: the node itself acts as the initial match selection, and the root node of the containing tree acts as the global context item.
-
Optionally, an initial mode.
[Definition: The initial mode is the mode used to select template rules for processing items in the initial match selection when apply-templates invocation is used to initiate a transformation.]
In searching for the template rule that best matches the items in the initial match selection, the processor considers only those rules that apply to the initial mode.
If no initial mode is supplied explicitly, then the initial mode is that named in the
default-modeattribute of the (explicit or implicit)xsl:packageelement of the top-level package or in the absence of such an attribute, the unnamed mode.[ERR XTDE0044] It is a dynamic error if the invocation of the stylesheet specifies an initial mode when no initial match selection is supplied (either explicitly, or defaulted to the global context item).
A (named or unnamed) mode M is eligible as an initial mode if one of the following conditions applies, where P is the top-level package of the stylesheet:
-
M is explicitly declared in an
xsl:modedeclaration within P, and haspublicorfinalvisibility (either by virtue of itsvisibilityattribute, or by virtue of anxsl:exposedeclaration). -
M is the unnamed mode.
-
M is named in the
default-modeattribute of the (explicit or implicit)xsl:packageelement of P. -
M is declared in a package used by P, and is given
publicorfinalvisibility in P by means of anxsl:acceptdeclaration. -
The effective value of the
declared-modesattribute of the explicit or implicitxsl:packageelement of P isno, and M appears as a mode-name in themodeattribute of a template rule declared within P.
[ERR XTDE0045] It is a dynamic error if the invocation of the stylesheet specifies an initial mode and the specified mode is not eligible as an initial mode (as defined above).
-
-
Parameters, which will be passed to the template rules used to process items in the input sequence. The parameters consist of two sets of (QName, value) pairs, one set for tunnel parameters and one for non-tunnel parameters, in which the QName identifies the name of a parameter and the value provides the value of the parameter. Either or both sets of parameters may be empty. The effect is the same as when a template is invoked using
xsl:apply-templateswith anxsl:with-paramchild specifyingtunnel="yes"ortunnel="no"as appropriate. If a parameter is supplied that is not declared or used, the value is simply ignored. These parameters are not used to set stylesheet parameters.A supplied value is converted if necessary to the declared type of the template parameter using the function conversion rules.
-
Details of how the result of the initial template is to be returned. For details, see 2.3.6 Post-processing the Raw Result
The raw result of the invocation is the
result of processing the supplied input sequence as if by a call on
xsl:apply-templates in the specified mode: specifically, each
item in the input sequence is processed by selecting and evaluating the best
matching template rule, and converting the result (if necessary) to the type
declared in the as attribute of that template using the function conversion rules; and the results of processing each item
are then concatenated into a single sequence, respecting the order of items in the
input sequence.
Note:
If the initial mode is declared-streamable, then a streaming processor should allow some or all of the items in the initial match selection to be nodes supplied in streamable form, and any nodes that are supplied in this form must then be processed using streaming.
Since the global context item cannot be a streamed node, in cases where the transformation is to proceed by applying streamable templates to a streamed input document, the global context item must either be absent, or must be something that differs from the initial match selection.
Note:
The design of the API for invoking a transformation should provide some means for users to designate the unnamed mode as the initial mode in cases where it is not the default mode.
It is a dynamic error
[see ERR XTDE0700] if the template rule selected for processing any item in the initial match selection defines a template parameter that specifies required="yes"
and no value is supplied for that
parameter.
Note:
A stylesheet can process further source
documents in addition to those supplied when the transformation is invoked.
These additional documents can be loaded using the functions
document (see 20.1 fn:document) or
docFO30 or collectionFO30 (see [Functions and Operators 3.0]), or using the
xsl:source-document instruction; alternatively, they can
be supplied as stylesheet
parameters (see 9.5 Global Variables and Parameters), or returned as
the result of an extension
function (see 24.1 Extension Functions).
2.3.4 Call-Template Invocation
[Definition: A stylesheet may be evaluated by selecting a
named template to be evaluated; this is referred to as the initial named
template.] The effect is analogous to the effect of
executing an xsl:call-template instruction. The following
information is needed in this case:
-
Optionally, the name of the initial named template which is to be executed as the entry point to the transformation. If no template name is supplied, the default template name is
xsl:initial-template. The selected template must exist within the stylesheet. -
Optionally, a context item for evaluation of this named template, defaulting to the global context item if it exists. This is constrained by any
xsl:context-itemelement appearing within the selectedxsl:templateelement. The initial named template is evaluated with a singleton focus based on this context item if it exists, or with an absent focus otherwise. -
Parameters, which will be passed to the selected template rule. The parameters consist of two sets of (QName, value) pairs, one set for tunnel parameters and one for non-tunnel parameters, in which the QName identifies the name of a parameter and the value provides the value of the parameter. Either or both sets of parameters may be empty. The effect is the same as when a template is invoked using
xsl:call-templatewith anxsl:with-paramchild specifyingtunnel="yes"ortunnel="no"as appropriate. If a parameter is supplied that is not declared or used, the value is simply ignored. These parameters are not used to set stylesheet parameters.A supplied value is converted if necessary to the declared type of the template parameter using the function conversion rules.
-
Details of how the result of the initial named template is to be returned. For details, see 2.3.6 Post-processing the Raw Result
The raw result of the invocation is the
result of evaluating the initial named template, after
conversion of the result to the type declared in the as attribute of
that template using the function conversion rules, if such
conversion is necessary.
The initial named template is evaluated in final output state.
[ERR XTDE0040] It is a dynamic error if the invocation of
the stylesheet specifies a template
name that does not match the expanded
QName of a named template defined in the stylesheet, whose
visibility is public or final.
It is a dynamic error
[see ERR XTDE0700] if the initial named template, or any of the template rules invoked to
process items in the initial match selection, defines a
template parameter that
specifies required="yes"
and no value is supplied for that parameter.
2.3.5 Function Call Invocation
[Definition: A stylesheet may be evaluated by calling a named stylesheet function, referred to as the initial function.] The following additional information is needed in this case:
-
The name and arity of a stylesheet function which is to be executed as the entry point to the transformation.
Note:
In the design of a concrete API, the arity may be inferred from the length of the parameter list.
-
A list of values to act as parameters to the initial function. The number of values in the list must be the same as the arity of the function.
A supplied value is converted if necessary to the declared type of the function parameter using the function conversion rules.
-
Details of how the result of the initial function is to be returned. For details, see 2.3.6 Post-processing the Raw Result
The raw result of the invocation is the
result of evaluating the initial function, after conversion of
the result to the type declared in the as attribute of that function
using the function conversion rules, if such conversion is
necessary.
Note:
The initial function (like all stylesheet functions) is evaluated with an absent focus.
If the initial function is declared-streamable, a streaming processor should allow the value of the first argument to be supplied in streamable form, and if it is supplied in this form, then it must be processed using streaming.
[ERR XTDE0041] It is a dynamic error if the invocation of the stylesheet specifies a function name and
arity that does not match the expanded
QName and arity of a named stylesheet function defined in the stylesheet, whose visibility is
public or final.
When a transformation is invoked by calling an initial function, the entire transformation executes in temporary output state, which means that calls on
xsl:result-document are not permitted.
2.3.6 Post-processing the Raw Result
There are three ways the result of a transformation
may be delivered. (This applies both to the principal result, described here, and
also to secondary results, generated using xsl:result-document.)
-
The raw result (a sequence of values) may be returned directly to the calling application.
-
A result tree may be constructed from the raw result. By default, a result tree is constructed if the
build-treeattribute of the unnamed output definition has the effective valueyes. An API for invoking transformations may allow this setting to be overridden by the calling application. If result tree construction is requested, it is performed as described in 2.3.6.1 Result Tree Construction. -
Alternatively, the raw result may be serialized as described in 2.3.6.2 Serializing the Result. The decision whether or not to serialize the result is determined by the rules of transformation API provided by the processor, and is not influenced by anything in the stylesheet.
Note:
This specification does not constrain the design of application programming interfaces or the choice of defaults. In previous versions of this specification, result tree construction was a mandatory process, while serialization was optional. When invoking stylesheet functions directly, however, result tree construction and serialization may be inappropriate as defaults. These considerations may affect the design of APIs.
In previous versions of XSLT, results were delivered either
in serialized form (as a character or byte stream), or as a tree. In the latter case
processors
typically would use either their own tree representation, or a standardized tree
representation such as the W3C Document Object Model (DOM) (see [DOM Level 2]),
adapted to the data structures offered by the programming language in which the API
is defined.
To deliver a raw result, processors need to define a representation not only of XDM
nodes but
also of sequences, atomic values, maps and even functions. As with the return of a
simple tree,
this may involve a trade-off between strict fidelity to the XDM data model and usability
in the particular
programming language environment. It is not a requirement that an API should return results
in a way that exposes every property of the XDM data model; for example there may
be APIs that do not expose
the precise type annotation of a returned node or atomic value, or that fail to expose
the base URI
or document URI of a node, or that provide no way of determining whether two nodes
in the result
sequence are the same node in the sense of the XPath is operator.
The way in which maps and functions (and where XPath 3.1 is supported, arrays)
are returned requires careful design choices. It is recommended that an API should be capable
of returning any XDM value without error, and that there should be minimal loss of
information if
the raw results output by one transformation are subsequently used as input to another
transformation.
2.3.6.1 Result Tree Construction
If a result tree is to be constructed from the raw result, then this is done
by applying the rules for the process of sequence normalizationSER30 as defined in
[XSLT and XQuery Serialization]. This process takes as input the serialization parameters defined in the
unnamed output definition of the top-level package; though the only parameter
that is actually used by this process is item-separator. In particular, sequence normalization is carried
out regardless of any method attribute in the unnamed output definition.
The sequence normalization process either returns a document node, or raises a serialization error. The content of the document node is not necessarily well-formed (the document node may have any number of element or text nodes among its children).
Note:
More specifically, the process raises a serialization error if any item in the raw result is an attribute node, a namespace node, or a function (including a map, but not an array: arrays are flattened).
The tree that is constructed is referred to as a final result tree.
If the raw result is an empty sequence, the final result tree will consist of a document node with no children.
The base URI of the document node is set to the base output URI.
Note:
The item-separator property has no effect if the raw result of the transformation is a sequence
of length zero or one, which in practice will often be the case, especially in a traditional
scenario such as
transformation of an XML document to HTML.
If there is no item-separator, then a single space is inserted between adjacent atomic values;
for example if the raw result is the sequence 1 to 5, then sequence normalization produces a tree
comprising a document node with a single child, the child being a text node with the
string value
1 2 3 4 5.
If there is an item-separator, then it is used not only between adjacent atomic values,
but between any pair of items in the raw result. For example if the raw result is
a sequence of two
element nodes A and B, and the item-separator is a comma,
then the result of sequence normalization will be a document node with three children:
a copy of A,
a text node whose string value is a single comma, and a copy of B.
2.3.6.2 Serializing the Result
See 2.7 Parsing and Serialization.
The raw result may optionally be serialized as described in 26 Serialization. The serialization is controlled by the serialization parameters defined in the unnamed output definition of the top-level package.
Note:
The first phase of serialization, called sequence normalizationSER30,
takes place for some output methods but not others. For example, if the json output method
(defined in [XSLT and XQuery Serialization 3.1]) is selected, then the process of constructing
a tree is bypassed.
The effect of serialization is to generate a sequence of octets, representing the serialized result in some character encoding. The processor’s API may define mechanisms enabling this sequence of octets to be written to persistent storage at some location. The default location is the location identified by the base output URI.
In previous versions of this specification it was stated that
when the raw result of the initial template or function is an empty sequence,
a result tree should be produced if and only if the transformation generates no secondary
results
(that is, if it does not invoke xsl:result-document). This provision is most likely
to have a noticeable effect if the transformation produces serialized results, and
these results
are written to persistent storage: the effect is then that a transformation producing
an empty
principal result will overwrite any existing content at the base output URI location
if and only
if the transformation produces no other output. Processor APIs offering backwards
compatibility
with earlier versions of XSLT must respect this behavior, but there is no requirement
for new
processor APIs to do so.
[Definition: The base output URI is a URI to be used as the base URI when
resolving a relative URI reference allocated
to a final result tree. If the
transformation generates more than one final result tree, then typically each
one will be allocated a URI relative to this base URI.] The way in
which a base output URI is established is implementation-defined. Each invocation of the stylesheet may supply
a different base output URI. It is acceptable for the base output URI to be
absent, provided no constructs (such as
xsl:result-document) are evaluated that depend on the value of
the base output URI.
Note:
It will often be convenient for the base output URI to be the same as the location to which the principal result document is serialized, but this relationship is not a necessary one.
2.4 Instructions
The main executable components of a stylesheet are templates and functions. The body of a template or function is a sequence constructor, which is a sequence of elements and text nodes that can be evaluated to produce a result.
A sequence constructor is a sequence of sibling nodes in the stylesheet, each of which is either an XSLT instruction, a literal result element, a text node, or an extension instruction.
[Definition: An instruction is either an XSLT instruction or an extension instruction.]
[Definition: An XSLT
instruction is an XSLT element
whose syntax summary in this specification contains the annotation <!--
category: instruction -->.]
Extension instructions are described in 24.2 Extension Instructions.
The main categories of XSLT instruction are as follows:
-
instructions that create new nodes:
xsl:document,xsl:element,xsl:attribute,xsl:processing-instruction,xsl:comment,xsl:value-of,xsl:text,xsl:namespace; -
instructions that copy nodes:
xsl:copy,xsl:copy-of; -
an instruction that returns an arbitrary sequence by evaluating an XPath expression:
xsl:sequence; -
instructions that cause conditional or repeated evaluation of nested instructions:
xsl:if,xsl:choose,xsl:try,xsl:for-each,xsl:for-each-group,xsl:fork,xsl:iterateand its subordinate instructionsxsl:next-iterationandxsl:break; -
instructions that generate output conditionally if elements are or are not empty:
xsl:on-empty,xsl:on-non-empty,xsl:where-populated; -
instructions that invoke templates:
xsl:apply-templates,xsl:apply-imports,xsl:call-template,xsl:next-match; -
Instructions that declare variables:
xsl:variable; -
Instructions to assist debugging:
xsl:message,xsl:assert; -
other specialized instructions:
xsl:number,xsl:analyze-string,xsl:fork,xsl:result-document,xsl:source-document,xsl:perform-sort,xsl:merge.
2.5 Rule-Based Processing
The classic method of executing an XSLT transformation is to apply template rules to the root node of an input document (see 2.3.3 Apply-Templates Invocation). The operation of applying templates to a node searches the stylesheet for the best matching template rule for that node. This template rule is then evaluated. A common coding pattern, especially when XSLT is used to convert XML documents into display formats such as HTML, is to have one template rule for each kind of element in the source document, and for that template rule to generate some appropriate markup elements, and to apply templates recursively to its own children. The effect is to perform a recursive traversal of the source tree, in which each node is processed using the best-fit template rule for that node. The final result of the transformation is then the tree produced by this recursive process. This result can then be optionally serialized (see 2.3.6 Post-processing the Raw Result).
This example uses rule-based processing to convert a simple XML input document into an HTML output document.
The input document takes the form:
<PERSONAE PLAY="OTHELLO"> <TITLE>Dramatis Personae</TITLE> <PERSONA>DUKE OF VENICE</PERSONA> <PERSONA>BRABANTIO, a senator.</PERSONA> <PERSONA>Other Senators.</PERSONA> <PERSONA>GRATIANO, brother to Brabantio.</PERSONA> <PERSONA>LODOVICO, kinsman to Brabantio.</PERSONA> <PERSONA>OTHELLO, a noble Moor in the service of the Venetian state.</PERSONA> <PERSONA>CASSIO, his lieutenant.</PERSONA> <PERSONA>IAGO, his ancient.</PERSONA> <PERSONA>RODERIGO, a Venetian gentleman.</PERSONA> <PERSONA>MONTANO, Othello's predecessor in the government of Cyprus.</PERSONA> <PERSONA>Clown, servant to Othello. </PERSONA> <PERSONA>DESDEMONA, daughter to Brabantio and wife to Othello.</PERSONA> <PERSONA>EMILIA, wife to Iago.</PERSONA> <PERSONA>BIANCA, mistress to Cassio.</PERSONA> <PERSONA>Sailor, Messenger, Herald, Officers, Gentlemen, Musicians, and Attendants.</PERSONA> </PERSONAE>
The stylesheet to render this as HTML can be written as a set of template rules:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" expand-text="yes"> <xsl:strip-space elements="PERSONAE"/> <xsl:template match="PERSONAE"> <html> <head> <title>The Cast of {@PLAY}</title> </head> <body> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="TITLE"> <h1>{.}</h1> </xsl:template> <xsl:template match="PERSONA[count(tokenize(., ',') = 2]"> <p><b>{substring-before(., ',')}</b>: {substring-after(., ',')}</p> </xsl:template> <xsl:template match="PERSONA"> <p><b>{.}</b></p> </xsl:template> </xsl:stylesheet>
There are four template rules here:
-
The first rule matches the outermost element, named
PERSONAE(it could equally have usedmatch="/"to match the document node). The effect of this rule is to create the skeleton of the output HTML page. Technically, the body of the template is a sequence constructor comprising a single literal result element (thehtmlelement); this in turn contains a sequence constructor comprising two literal result elements (theheadandbodyelements). Theheadelement is populated with a literaltitleelement whose content is computed as a mixture of fixed and variable text using a text value template. Thebodyelement is populated by evaluating anxsl:apply-templatesinstruction.The effect of the
xsl:apply-templatesinstruction is to process the children of thePERSONAEelement in the source tree: that is, theTITLEandPERSONAelements. (It would also process any whitespace text node children, but these have been stripped by virtue of thexsl:strip-spacedeclaration.) Each of these child elements is processed by the best matching template rule for that element, which will be one of the other three rules in the stylesheet. -
The template rule for the
TITLEelement outputs anh1element to the HTML result document, and populates this with the value of ".", the context item. That is, it copies the text content of theTITLEelement to the outputh1element. -
The last two rules match
PERSONAelement. The first rule matchesPERSONAelements whose text content contains exactly one comma; the second rule matches allPERSONAelements, but it has lower priority than the first rule, so in practice it only applies toPERSONAelements that contain no comma or multiple commas.For both rules the body of the rule is a sequence constructor containing a single literal result element, the
pelement. These literal result elements contain further sequence constructors comprising literal result elements and text nodes. In each of these examples the text nodes are in the form of a text value template: in general this is a combination of fixed text together with XPath expressions enclosed in curly braces, which are evaluated to form the content of the containing literal result element.
[Definition: A stylesheet contains a set of template rules (see 6 Template Rules). A template rule has three parts: a pattern that is matched against selected items (often but not necessarily nodes), a (possibly empty) set of template parameters, and a sequence constructor that is evaluated to produce a sequence of items.] In many cases these items are newly constructed nodes, which are then written to a result tree.
2.6 The Evaluation Context
The results of some expressions and instructions in a stylesheet may depend on information provided contextually. This context information is divided into two categories: the static context, which is known during static analysis of the stylesheet, and the dynamic context, which is not known until the stylesheet is evaluated. Although information in the static context is known at analysis time, it is sometimes used during stylesheet evaluation.
Some context information can be set by means of declarations within the stylesheet itself. For example, the namespace bindings used for any XPath expression are determined by the namespace declarations present in containing elements in the stylesheet. Other information may be supplied externally or implicitly: an example is the current date and time.
The context information used in processing an XSLT stylesheet includes as a subset
all the context information required when evaluating XPath expressions. The XPath 3.0 specification defines a static and dynamic
context that the host language (in this case, XSLT) may initialize, which affects
the
results of XPath expressions used in that context. XSLT augments the context with
additional information: this additional information is used firstly by XSLT
constructs outside the scope of XPath (for example, the xsl:sort
element), and secondly, by functions that are defined in the XSLT specification (such
as key and current-group) that are
available for use in XPath expressions appearing within a stylesheet.
The static context for an expression or other construct in a stylesheet is determined by the place in which it appears lexically. The details vary for different components of the static context, but in general, elements within a stylesheet module affect the static context for their descendant elements within the same stylesheet module.
The dynamic context is maintained as a stack. When an instruction or expression is evaluated, it may add dynamic context information to the stack; when evaluation is complete, the dynamic context reverts to its previous state. An expression that accesses information from the dynamic context always uses the value at the top of the stack.
The most commonly used component of the dynamic context is the context item. This is an implicit variable whose
value is the item currently being processed (it may be a node, an atomic value,
or a function item). The value of the context
item can be referenced within an XPath expression using the expression .
(dot).
Full details of the static and dynamic context are provided in 5.3 The Static and Dynamic Context.
2.7 Parsing and Serialization
An XSLT stylesheet
describes a process that constructs a set of results from a set of inputs. The inputs
are the data provided at stylesheet invocation, as described in 2.3 Initiating a Transformation. The results include the principal result
(an arbitrary sequence), which is the result of the initial component invocation,
together with any secondary results
produced using xsl:result-document instructions.
The stylesheet does not describe how a source tree is constructed. Some possible ways of constructing source trees are described in [XDM 3.0]. Frequently an implementation will operate in conjunction with an XML parser (or more strictly, in the terminology of [XML 1.0], an XML processor), to build a source tree from an input XML document. An implementation may also provide an application programming interface allowing the tree to be constructed directly, or allowing it to be supplied in the form of a DOM Document object (see [DOM Level 2]). This is outside the scope of this specification. Users should be aware, however, that since the input to the transformation is a tree conforming to the XDM data model as described in [XDM 3.0], constructs that might exist in the original XML document, or in the DOM, but which are not within the scope of the data model, cannot be processed by the stylesheet and cannot be guaranteed to remain unchanged in the transformation output. Such constructs include CDATA section boundaries, the use of entity references, and the DOCTYPE declaration and internal DTD subset.
[Definition: A frequent requirement is to output a final result tree as an XML document (or in other formats such as HTML). This process is referred to as serialization.]
Like parsing, serialization is not part of the transformation process, and it is not
required that an XSLT processor must be able
to perform serialization. However, for pragmatic reasons, this specification
describes declarations (the xsl:output element and the
xsl:character-map declarations, see 26 Serialization), and attributes on the xsl:result-document instruction, that
allow a stylesheet to specify the desired
properties of a serialized output file. When serialization is not being performed,
either because the implementation does not support the serialization option, or
because the user is executing the transformation in a way that does not invoke
serialization, then the content of the xsl:output and
xsl:character-map declarations has no effect. Under these
circumstances the processor may report any errors in an
xsl:output or xsl:character-map declaration, or
in the serialization attributes of xsl:result-document, but is not
required to do so.
2.8 Packages and Modules
In previous versions of the XSLT language, it has been possible to structure a
stylesheet as a collection of modules, using the xsl:include and
xsl:import declarations to express the dependency of one module on
others.
In XSLT 3.0 an additional layer of modularization of stylesheet code is enabled through the introduction of packages. A package is a collection of stylesheet modules with a controlled interface to the packages that use it: for example, it defines which functions and templates defined in the package are visible to callers, which are purely internal, and which are not only public but capable of being overridden by other functions and templates supplied by the using package.
Packages are introduced with several motivations, which broadly divide into two categories:
-
Software engineering benefits: greater re-use of code, greater robustness through ease of testing, controlled evolution of code in response to new requirements, ability to deliver code that users cannot see or modify.
-
Efficiency benefits: the ability to avoid compiling libraries repeatedly when they are used in multiple stylesheets, and to avoid holding multiple copies of the same library in memory simultaneously.
Packages are designed to allow separate compilation: that is, a package can be compiled independently of the packages that use it. This specification does not define a process model for compilation, or expand on what it means to compile different packages independently. Nor does it mandate that implementations offer any feature along these lines. It merely defines language features that are designed to make separate compilation of packages possible.
To achieve this, packages (unlike modules):
-
Must not contain unresolved references to functions, templates, or variables declared in other packages;
-
Have strict rules governing the ability to override declarations in a library package with declarations in a package that uses the library;
-
Constrain the visibility of component names and of context declarations such as the declarations of keys and decimal formats;
-
Can declare a mode (a collection of template rules) as final, which disallows the addition of new overriding template rules in a using package;
-
Require explicit disambiguation where naming conflicts arise, for example when a package uses two other packages that both export like-named components;
-
Allow multiple specializations of library components to coexist in the same application.
A package is defined in XSLT
by means of an XML document whose
outermost element is an xsl:package element. This is referred to as
the package manifest. The xsl:package element
has optional child elements xsl:use-package and
xsl:expose describing properties of the package. The package
manifest may refer to an external top-level stylesheet module using an
xsl:include or xsl:import declaration, or it may
contain the body of a stylesheet module inline (the two approaches can also be
mixed).
Although this specification defines packages as constructs written using a defined XSLT syntax, implementations may provide mechanisms that allow packages to be written using other languages (for example, XQuery).
When no packages are explicitly defined, the entire
stylesheet is treated as a single package; the effect is as if the
xsl:stylesheet or xsl:transform element of the
principal stylesheet
module were replaced by an xsl:package element with no
other information in the package manifest.
2.9 Extensibility
XSLT defines a number of features that allow the language to be extended by implementers, or, if implementers choose to provide the capability, by users. These features have been designed, so far as possible, so that they can be used without sacrificing interoperability. Extensions other than those explicitly defined in this specification are not permitted.
These features are all based on XML namespaces; namespaces are used to ensure that the extensions provided by one implementer do not clash with those of a different implementer.
The most common way of extending the language is by providing additional functions, which can be invoked from XPath expressions. These are known as extension functions, and are described in 24.1 Extension Functions.
It is also permissible to extend the language by providing new instructions. These are referred to as extension instructions, and are described
in 24.2 Extension Instructions. A stylesheet that uses extension
instructions in a particular namespace must declare that it is doing so by using the
[xsl:]extension-element-prefixes attribute.
Extension instructions and extension functions defined according to these rules may be provided by the implementer of the XSLT processor, and the implementer may also provide facilities to allow users to create further extension instructions and extension functions.
This specification defines how extension instructions and extension functions are invoked, but the facilities for creating new extension instructions and extension functions are implementation-defined. For further details, see 24 Extensibility and Fallback.
The XSLT language can also be extended by the use of extension attributes (see 3.2 Extension Attributes), and by means of user-defined data elements (see 3.7.3 User-defined Data Elements).
2.10 Stylesheets and XML Schemas
An XSLT stylesheet can make use of information from a schema. An XSLT transformation can take place in the absence of a schema (and, indeed, in the absence of a DTD), but where the source document has undergone schema validity assessment, the XSLT processor has access to the type information associated with individual nodes, not merely to the untyped text.
Information from a schema can be used both statically (when the stylesheet is compiled), and dynamically (during evaluation of the stylesheet to transform a source document).
There are places within a stylesheet, and within XPath expressions and patterns in a stylesheet, where it is possible to refer to named type definitions in a schema, or to element and attribute declarations. For example, it is possible to declare the types expected for the parameters of a function. This is done using a SequenceType.
[Definition: A SequenceType constrains the type and number of items in a sequence. The term is used both to denote the concept, and to refer to the syntactic form in which sequence types are expressed in the XPath grammar: specifically SequenceTypeXP30 in [XPath 3.0], or SequenceTypeXP31 in [XPath 3.1], depending on whether or not the XPath 3.1 Feature is implemented.]
[Definition: Type definitions and element and attribute declarations are referred to collectively as schema components.]
[Definition: The schema components that may be referenced by name in a package are referred to as the in-scope schema components.]
The set of in-scope schema components may vary between one package and another, but as explained in 3.15 Importing Schema Components, the schema components used in different packages must be consistent with each other.
The conformance rules for XSLT 3.0, defined in
27 Conformance, distinguish between a basic XSLT processor and a schema-aware XSLT processor. As the
names suggest, a basic XSLT processor does not support the features of XSLT that
require access to schema information, either statically or dynamically. A stylesheet that works with a basic XSLT processor
will produce the same results with a schema-aware XSLT processor provided that the
source documents are untyped (that is, they are not validated against a schema).
However, if source documents are validated against a schema then the results may be
different from the case where they are not validated. Some constructs that work on
untyped data may fail with typed data (for example, an attribute of type
xs:date cannot be used as an argument of the
substringFO30 function) and other constructs may produce
different results depending on the datatype (for example, given the element
<product price="10.00" discount="2.00"/>, the expression
@price gt @discount will return true if the attributes have type
xs:decimal, but will return false if they are untyped).
There is a standard set of type definitions that are always available as in-scope schema components in every stylesheet. These are defined in 3.14 Built-in Types.
The remainder of this section describes facilities that are available only with a schema-aware XSLT processor.
Additional schema components (type
definitions, element declarations, and attribute declarations) may be added to the
in-scope schema components
by means of the xsl:import-schema declaration in a stylesheet.
The xsl:import-schema declaration may reference an external schema
document by means of a URI, or it may contain an inline xs:schema
element.
It is only necessary to import a schema explicitly if one or more of its schema components are referenced explicitly by name in the stylesheet; it is not necessary to import a schema merely because the stylesheet is used to process a source document that has been assessed against that schema. It is possible to make use of the information resulting from schema assessment (for example, the fact that a particular attribute holds a date) even if no schema has been imported by the stylesheet.
Importing a schema does not of itself say anything about the type of the source document that the stylesheet is expected to process. The imported type definitions can be used for temporary nodes or for nodes on a result tree just as much as for nodes in source documents. It is possible to make assertions about the type of an input document by means of tests within the stylesheet. For example:
<xsl:mode typed="lax"/> <xsl:global-context-item use="required" as="document-node(schema-element(my:invoice))"/>
This example will cause the transformation to fail with an error message, unless
the global context item is valid against the top-level element
declaration my:invoice, and has been annotated as such.
The setting typed="lax" further ensures that in any
match pattern for a template rule in this mode, an element name that corresponds
to the name of an element declaration in the schema is taken as referring to
elements validated against that declaration: for example,
match="employee" will only match a validated employee
element. Selecting this option enables the XSLT processor to do more compile-time
type-checking against the schema, for example it allows the processor to produce
warning or error messages when path expressions contain misspelt element names, or
confuse an element with an attribute.
It is also true that importing a schema does not of itself say
anything about the structure of the result tree. It is possible to request validation
of a result tree against the schema by using the xsl:result-document
instruction, for example:
<xsl:template match="/"> <xsl:result-document validation="strict"> <xhtml:html> <xsl:apply-templates/> </xhtml:html> </xsl:result-document> </xsl:template>
This example will cause the transformation to fail with an error message unless
the document element of the result document is valid against the top-level element
declaration xhtml:html.
It is possible that a source document may contain nodes whose type annotation is not one of the types
imported by the stylesheet. This creates a potential problem because in the case of
an expression such as data(.) instance of xs:integer the system needs to
know whether the type named in the type annotation of the context node is derived
by
restriction from the type xs:integer. This information is not explicitly
available in an XDM tree, as defined in [XDM 3.0]. The
implementation may choose one of several strategies for dealing with this
situation:
-
The processor may signal a dynamic error if a source document is found to contain a type annotation that is not known to the processor.
-
The processor may maintain additional metadata, beyond that described in [XDM 3.0], that allows the source document to be processed as if all the necessary schema information had been imported using
xsl:import-schema. Such metadata might be held in the data structure representing the source document itself, or it might be held in a system catalog or repository. -
The processor may be configured to use a fixed set of schemas, which are automatically used to validate all source documents before they can be supplied as input to a transformation. In this case it is impossible for a source document to have a type annotation that the processor is not aware of.
-
The processor may be configured to treat the source document as if no schema processing had been performed, that is, effectively to strip all type annotations from elements and attributes on input, marking them instead as having type
xs:untypedandxs:untypedAtomicrespectively.
Where a stylesheet author chooses to make assertions about the types of nodes or of variables and parameters, it is possible for an XSLT processor to perform static analysis of the stylesheet (that is, analysis in the absence of any source document). Such analysis may reveal errors that would otherwise not be discovered until the transformation is actually executed. An XSLT processor is not required to perform such static type-checking. Under some circumstances (see 2.14 Error Handling) type errors that are detected early may be reported as static errors. In addition an implementation may report any condition found during static analysis as a warning, provided that this does not prevent the stylesheet being evaluated as described by this specification.
A stylesheet can also control the type annotations of nodes that it constructs in a result tree. This can be done in a number of ways.
-
It is possible to request explicit validation of a complete document, that is, a result tree rooted at a document node. Validation is either strict or lax, as described in [XML Schema Part 1]. If validation of a result tree fails (strictly speaking, if the outcome of the validity assessment is
invalid), then the transformation fails, but in all other cases, the element and attribute nodes of the tree will be annotated with the names of the types to which these nodes conform. These type annotations will be discarded if the result tree is serialized as an XML document, but they remain available when the result tree is passed to an application (perhaps another stylesheet) for further processing. -
It is also possible to validate individual element and attribute nodes as they are constructed. This is done using the
typeandvalidationattributes of thexsl:element,xsl:attribute,xsl:copy, andxsl:copy-ofinstructions, or thexsl:typeandxsl:validationattributes of a literal result element. -
When elements, attributes, or document nodes are copied, either explicitly using the
xsl:copyorxsl:copy-ofinstructions, or implicitly when nodes in a sequence are attached to a new parent node, the optionsvalidation="strip"andvalidation="preserve"are available, to control whether existing type annotations are to be retained or not.
When nodes in a temporary tree are validated, type information is available for use by operations carried out on the temporary tree, in the same way as for a source document that has undergone schema assessment.
For details of how validation of element and attribute nodes works, see 25.4 Validation.
2.11 Streaming
[Definition: The term streaming refers to a manner of processing in which XML documents (such as source and result documents) are not represented by a complete tree of nodes occupying memory proportional to document size, but instead are processed “on the fly” as a sequence of events, similar in concept to the stream of events notified by an XML parser to represent markup in lexical XML.]
[Definition: A streamed document is a source tree that is processed using streaming, that is, without constructing a complete tree of nodes in memory.]
[Definition: A streamed node is a node in a streamed document.]
Many processors implementing earlier versions of this specification have adopted an architecture that allows streaming of the result tree directly to a serializer, without first materializing the complete result tree in memory. Streaming of the source tree, however, has proved to be more difficult without subsetting the language. This has created a situation where documents exceeding the capacity of virtual memory could not be transformed. XSLT 3.0 therefore introduces facilities allowing stylesheets to be written in a way that makes streaming of source documents possible, without excessive reliance on processor-specific optimization techniques.
Streaming achieves two important objectives: it allows large documents to be transformed without requiring correspondingly large amounts of memory; and it allows the processor to start producing output before it has finished receiving its input, thus reducing latency.
This specification does not attempt to legislate precisely which implementation techniques fall under the definition of streaming, and which do not. A number of techniques are available that reduce memory requirements, while still requiring a degree of buffering, or allocation of memory to partial results. A stylesheet that requests streaming of a source document is indicating that the processor should avoid assuming that the entire source document will fit in memory; in return, the stylesheet must be written in a way that makes streaming possible. This specification does not attempt to describe the algorithms that the processor should actually use, or to impose quantitative constraints on the resources that these algorithms should consume.
Nothing in this specification, nor in its predecessors [XSLT 1.0] and [XSLT 2.0], prevents a processor using streaming whenever it sees an opportunity to do so. However, experience has shown that in order to achieve streaming, it is often necessary to write stylesheet code in such a way as to make this possible. Therefore, XSLT 3.0 provides explicit constructs allowing the stylesheet author to request streaming, and defines explicit static constraints on the structure of the code which are designed to make streaming possible.
A processor that claims conformance with the streaming option offers a guarantee that when streaming is requested for a source document, and when the stylesheet conforms to the rules that make the processing guaranteed-streamable, then an algorithm will be adopted in which memory consumption is either completely independent of document size, or increases only very slowly as document size increases, allowing documents to be processed that are orders-of-magnitude larger than the physical memory available. A processor that does not claim conformance with the streaming option must still process a stylesheet and deliver the correct results, but is not required to use streaming algorithms, and may therefore fail with out-of-memory errors when presented with large source documents.
Apart from the fact that there are constructs to request streaming, and rules that must be followed to guarantee that streaming is possible, the language has been designed so there are as few differences as possible between streaming and non-streaming evaluation. The semantics of the language continue to be expressed in terms of the XDM data model, which is substantively unchanged; but readers must take care to observe that when terms like “node” and “axis” are used, the concepts are completely abstract and may have no direct representation in the run-time execution environment.
Streamed processing of a document can be initiated in one of three ways:
-
The initial mode can be declared as a streamable mode. In this case the initial match selection will generally be a document node (or sequence of document nodes), supplied by the calling application in a form that allows streaming (that is, in some form other than a tree in memory; for example, as a reference to a push or pull XML parser primed to deliver a stream of events). The type of these nodes can be constrained by using the attribute
on-no-match="fail"on the initial mode, and using this mode only for processing the top-level nodes. -
Streamed processing of any document can be initiated using the
xsl:source-documentinstruction. This has an attributehrefwhose value is the URI of a document to be processed, and an attributestreamablethat indicates whether it is to be processed using streaming; the actual processing to be applied is defined by the instructions written as children of thexsl:source-documentinstruction. -
Streamed merging of a set of input documents can be initiated using the
xsl:mergeinstruction.
The rules for streamability, which are defined in detail in 19 Streamability, impose two main constraints:
-
The only nodes reachable from the node that is currently being processed are its attributes and namespaces, its ancestors and their attributes and namespaces, and its descendants and their attributes and namespaces. The siblings of the node, and the siblings of its ancestors, are not reachable in the tree, and any attempt to use their values is a static error.
-
When processing a given node in the tree, each descendant node can only be visited once. Essentially this allows two styles of processing: either visit each of the children once, and then process that child with the same restrictions applied; or process all the descendants in a single pass, in which case it is not possible while processing a descendant to make any further downward selection.
The second restriction, that only one visit to the children is
allowed, means that XSLT code that was not designed with streaming in mind will often
need to be rewritten to make it streamable. In many cases it is possible to do this
using a technique sometimes called windowing or burst-mode
streaming (note this is not quite the same meaning as
windowing in XQuery 3.0). Many XML documents consist of a large
number of elements, each of manageable size, representing transactions or business
objects where each such element can be processed independently: in such cases, an
effective design pattern is to write a streaming transformation that takes a snapshot
of each element in turn, processing the snapshot using the full power of the XSLT
language. Each snapshot is a tree built in memory and is therefore fully navigable.
For details see the snapshot and copy-of
functions.
The new facility of accumulators allows applications complete control over how much information is retained (and by implication, how much memory is required) in the course of a pass over a streamed document. An accumulator computes a value for every node in a streamed document: or more accurately, two values, one for the first visit to a node (before visiting its descendants), and a second value for the second visit to the node (after visiting the descendants). The computation is structured in such a way that the value for a given node can depend only on the value for the previous node in document order together with the data available when positioned at the current node (for example, the attribute values). Based on the well-established fold operation of functional programming languages, accumulators provide the convenience and economy of mutable variables while remaining within the constraints of a purely declarative processing model.
When streaming is initiated, for example using the
xsl:source-document instruction, it is necessary to declare which
accumulators are applicable to the streamed document.
Streaming applications often fall into one of the following categories:
-
Aggregation applications, where a single aggregation operation (perhaps
countFO30,sumFO30,existsFO30, ordistinct-valuesFO30) is applied to a set of elements selected from the streamed source document by means of a path expression. -
Record-at-a-time applications, where the source document consists of a long sequence of elements with similar structure (“records”), and each “record” is processed using the same logic, independently of any other “records”. This kind of processing is facilitated using the
snapshotandcopy-offunction mentioned earlier. -
Grouping applications, where the output follows the structure of the input, except that an extra layer of hierarchy is added. For example, the input might be a flat series of banking transactions in date/time order, and the output might contain the same transactions grouped by date.
-
Accumulator applications, which are the same as record-at-a-time applications, except that the processing of one “record” might depend on data encountered earlier in the document. A classic example is processing a sequence of banking transactions in which the input transaction contains a debit or credit amount, and the output adds a running total (the account balance). The
xsl:iterateinstruction has been introduced to facilitate this style of processing. -
Isomorphic transformations, in which there is an ordered (often largely one-to-one) relationship between the nodes of the source tree and the nodes of the result tree: for example, transformations that involve only the renaming or selective deletion of nodes, or scalar manipulations of the values held in the leaf nodes. Such transformations are most conveniently expressed using recursive application of template rules. This is possible with a streamed input document only if all the template rules adhere to the constraints required for streamability. To enforce these rules, while still allowing unrestricted processing of other documents within the same transformation, all streaming evaluation must be carried out using a specific mode, which is declared to be a streaming mode by means of an
xsl:modedeclaration in the stylesheet.
There are important classes of application in which streaming is possible only if multiple streams can be processed in parallel. This specification therefore provides facilities:
-
allowing multiple sorted input sequences to be merged into one sorted output sequence (the
xsl:mergeinstruction) -
allowing multiple output sequences to be generated during a single pass of an input sequence (the
xsl:forkinstruction).
These facilities have been designed in such a way that they can readily be implemented using streaming, that is, without materializing the input or output sequences in memory.
2.12 Streamed Validation
Streaming can be combined with schema-aware processing: that is, the streamed input to a transformation can be subjected to on-the-fly validation, a process which typically accepts an input stream from the XML parser and delivers an output stream (of type-annotated nodes) to the transformation processor. The XSD specification is designed so that validation is, with one or two exceptions, a streamable process. The exceptions include:
-
There may be a need to allocate memory to hold keys, in order to enforce uniqueness and referential integrity constraints (
xs:unique,xs:key,xs:keyref). -
In XSD 1.1, assertions can be defined by means of XPath expressions. These are not constrained to be streamable; in the general case, any subtree of the document that is validated using an assertion may need to be buffered in memory while the assertion is processed.
Applications that need to run in finite memory may therefore need to avoid these XSD features, or to use them with care.
XSD is designed so that the intended type of an element (the “governing type”) can be determined as soon as the start tag of the element is encountered: the process of validation checks whether the content of the element actually conforms to this type, and by the time the end tag is encountered, the process will have established either that the element is valid against the governing type, or that it is invalid.
By default, dynamic errors occurring during streamed processing are fatal: they typically cause the transformation to fail immediately. XSLT 3.0 introduces the ability to catch dynamic errors and recover from them. Schema invalidity, however, is treated as a dynamic error of the instruction that processes the entire input stream, so after a validation failure, no further processing of that input stream is possible.
In consequence, a streamed validator that is running in tandem with a streamed transformation
can present the transformer with element nodes that carry a provisional type annotation
representing
the type that the element will have if it turns out to be valid. As soon as a node
is encountered that
violates this assumption, the validator should stop the flow of data to the transformer,
so that the
transformer never sees invalid data. This allows the stylesheet code to be compiled
with the assumption
of type-safety: at run-time, all nodes seen by the transformation will conform to
their XSLT-declared types
(for example, a type declared implicitly using match="schema-element(invoice)" on an
xsl:template element).
A streamed transformation that only accesses part of the input document (for example, a header at the start of a document) is not required to continue reading once the data it needs has been read. This means that XML well-formedness or validity errors occurring in the unread part of the input stream may go undetected.
2.13 Streaming of non-XML data
The facilities in this specification designed to enable large data sets to be processed in a streaming manner are oriented almost entirely to XML data. This does not mean that there is never a requirement to stream non-XML data, or that the Working Group has ignored this requirement; rather, the Working Group has concluded that for the most part, streaming of non-XML data can be achieved by implementations without the need for specific language features in XSLT.
To make streamed processing of unparsed text files easier, the function unparsed-text-linesFO30
has been introduced. This is not only more convenient for stylesheet authors than
reading the entire input
using the unparsed-textFO30 function and then tokenizing the result, it is also easier for implementations
to optimize, allowing each line of text to be discarded from memory after it has been
processed.
For all functions that access external data, including document, docFO30,
collectionFO30, unparsed-textFO30, unparsed-text-linesFO30,
and (in XPath 3.1) json-docFO31, the requirements on determinism can now
be relaxed using implementation-defined configuration options. This is significant
because it means that when a transformation reads the same external resource more
than once, it becomes
legitimate for the contents of the resource to be different on different invocations,
and this eliminates
the need for the processor to cache the contents of the resource in memory.
In the XDM data model, every value is a sequence, and (as with most functional programming languages), processing of sequences of items is pervasive throughout the XSLT and XPath languages and their function library. Good performance of a functional programming language often depends on sequence-based operations being pipelined, and being evaluated in a lazy fashion (that is, many operations process items in a sequence one at a time, in order; and many operations can deliver a result without processing the entire sequence). The semantics of XSLT and XPath permit pipelined and lazy evaluation (for example, the error handling semantics are carefully written to ensure this), but they do not require it: the details are left to implementations. Pipelined processing of a sequence is not the same thing as streamed processing of a tree, and where the XSLT specification talks of operations being “guaranteed streamable”, this is always referring to processing of trees, not of sequences.
The facilities for streaming of XML trees include operations such as copy-of
and snapshot which are able to take a sequence of streamed nodes as input,
and produce a sequence of in-memory (unstreamed) nodes as output. It is also possible
to generate
a sequence of strings or other atomic values through the process of atomization.
The actual memory usage of a streamed
XSLT application may depend significantly on whether the processing of the resulting
sequence of in-memory
nodes or atomic values is pipelined or not. The specification, however, has nothing
to say on this matter:
it is considered an area where implementers can exercise their discretion and ingenuity.
Streaming of JSON input receives little attention in this specification. One can envisage
an implementation
of the json-to-xml function in which the XML delivered by the function consists of
streamed nodes; but the Working Group has not researched the feasibility of such an
implementation in any detail.
2.14 Error Handling
[Definition: An error that can be detected by examining a stylesheet before execution starts (that is, before the source document and values of stylesheet parameters are available) is referred to as a static error.]
Generally, errors in the structure of the stylesheet, or in the syntax of XPath expressions contained in the stylesheet, are classified as static errors. Where this specification states that an element in the stylesheet must or must not appear in a certain position, or that it must or must not have a particular attribute, or that an attribute must or must not have a value satisfying specified conditions, then any contravention of this rule is a static error unless otherwise specified.
A processor must provide a mode of operation that takes a (possibly erroneous) stylesheet package as input and enables the user to determine whether or not that package contains any static errors.
Note:
The manner in which static errors are reported, and the behavior when there are multiple static errors, are left as design choices for the implementer. It is recommended that the error codes defined in this specification should be made available in any diagnostics.
A processor may also provide a mode of operation in which static errors in parts of the stylesheet that are not evaluated can go unreported.
Note:
For example, when operating in this mode, a processor might report static errors in a template rule only if the input document contains nodes that match that template rule. Such a mode of operation can provide performance benefits when large and well-tested stylesheets are used to process source documents that might only use a small part of the XML vocabulary that the stylesheet is designed to handle.
[Definition: An error that is not capable of detection until a source document is being transformed is referred to as a dynamic error.]
When a dynamic error occurs, and is not caught
using xsl:catch, the processor
must signal the error, and the transformation fails.
Because different implementations may optimize execution of the stylesheet in different ways, the detection of dynamic errors is to some degree implementation-dependent. In cases where an implementation is able to produce a principal result or secondary result without evaluating a particular construct, the implementation is never required to evaluate that construct solely in order to determine whether doing so causes a dynamic error. For example, if a variable is declared but never referenced, an implementation may choose whether or not to evaluate the variable declaration, which means that if evaluating the variable declaration causes a dynamic error, some implementations will signal this error and others will not.
There are some cases where this specification requires that a construct must
not be evaluated: for example, the content of an xsl:if
instruction must not be evaluated if the test condition is false.
This means that an implementation must not signal any dynamic
errors that would arise if the construct were evaluated.
An implementation may signal a dynamic error before any source document is available, but only if it can determine that the error would be signaled for every possible source document and every possible set of parameter values. For example, some circularity errors fall into this category: see 9.11 Circular Definitions.
There are also some dynamic
errors where the specification gives a processor license to signal the
error during the analysis phase even if the construct might never be executed; an
example is the use of an invalid QName as a literal argument to a function such as
key, or the use of an invalid regular expression in the
regex attribute of the xsl:analyze-string
instruction.
A dynamic error is also signaled during the static analysis phase if the error occurs during evaluation of a static expression.
The XPath specification states (see Section 2.3.1 Kinds of Errors XP30) that if any expression (at any level) can be evaluated during the analysis phase (because all its explicit operands are known and it has no dependencies on the dynamic context), then any error in performing this evaluation may be reported as a static error. For XPath expressions used in an XSLT stylesheet, however, any such errors must not be reported as static errors in the stylesheet unless they would occur in every possible evaluation of that stylesheet; instead, they must be signaled as dynamic errors, and signaled only if the XPath expression is actually evaluated.
An XPath processor may report statically that the expression 1 div 0
fails with a “divide by zero” error. But suppose this XPath expression occurs in
an XSLT construct such as:
<xsl:choose> <xsl:when test="system-property('xsl:version') = '1.0'"> <xsl:value-of select="1 div 0"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="xs:double('INF')"/> </xsl:otherwise> </xsl:choose>
Then the XSLT processor must not report an error, because the relevant XPath construct appears in a context where it will never be executed by an XSLT 2.0 or 3.0 processor. (An XSLT 1.0 processor will execute this code successfully, returning positive infinity, because it uses double arithmetic rather than decimal arithmetic.)
[Definition: Certain errors are classified as type errors. A type error occurs when the value supplied as input to an operation is of the wrong type for that operation, for example when an integer is supplied to an operation that expects a node.] If a type error occurs in an instruction that is actually evaluated, then it must be signaled in the same way as a dynamic error. Alternatively, an implementation may signal a type error during the analysis phase in the same way as a static error, even if it occurs in part of the stylesheet that is never evaluated, provided it can establish that execution of a particular construct would never succeed.
It is implementation-defined whether type errors are signaled statically.
The following construct contains a type error, because
42 is not allowed as the value of the select
expression of the xsl:number instruction (it must be a node). An
implementation may optionally signal this as a static error,
even though the offending instruction will never be evaluated, and the type error
would therefore never be signaled as a dynamic error.
<xsl:if test="false()"> <xsl:number select="42"/> </xsl:if>
On the other hand, in the following example it is not possible to determine
statically whether the operand of xsl:number will have a suitable dynamic type. An
implementation may produce a warning in such cases, but it
must not treat it as an error.
<xsl:template match="para"> <xsl:param name="p" as="item()"/> <xsl:number select="$p"/> </xsl:template>
If more than one error arises, an implementation is not required to signal any errors other than the first one that it detects. It is implementation-dependent which of the several errors is signaled. This applies both to static errors and to dynamic errors. An implementation is allowed to signal more than one error, but if any errors have been signaled, it must not finish as if the transformation were successful.
When a transformation signals one or more dynamic errors, the final state of any persistent resources updated by the transformation is implementation-dependent. Implementations are not required to restore such resources to their initial state. In particular, where a transformation produces multiple result documents, it is possible that one or more serialized result documents may be written successfully before the transformation terminates, but the application cannot rely on this behavior.
Everything said above about error handling applies equally to errors in evaluating XSLT instructions, and errors in evaluating XPath expressions. Static errors and dynamic errors may occur in both cases.
[Definition: If a transformation has successfully produced a principal result or secondary result, it is still possible that errors may occur in serializing that result . For example, it may be impossible to serialize the result using the encoding selected by the user. Such an error is referred to as a serialization error.] If the processor performs serialization, then it must do so as specified in 26 Serialization, and in particular it must signal any serialization errors that occur.
Errors are identified by a QName. For errors defined in this specification, the
namespace of the QName is always http://www.w3.org/2005/xqt-errors (and
is therefore not given explicitly), while the local part is an 8-character code in
the form PPSSNNNN. Here PP is always XT (meaning
XSLT), and SS is one of SE (static error), DE
(dynamic error), or TE
(type error). Note that the allocation of an error to one of these categories is
purely for convenience and carries no normative implications about the way the error
is handled. Many errors, for example, can be reported either dynamically or
statically. These error codes are used to label error conditions in this
specification, and are summarized in E Summary of Error Conditions.
Errors defined in related specifications ([XPath 3.0], [Functions and Operators 3.0] [XSLT and XQuery Serialization]) use QNames with a similar structure, in the same namespace. When errors occur in processing XPath expressions, an XSLT processor should use the original error code reported by the XPath processor, unless a more specific XSLT error code is available.
Implementations must use the codes
defined in these specifications when signaling dynamic errors, to ensure that
xsl:catch behaves in an interoperable way across
implementations. Stylesheet authors should note, however, that there are many
examples of errors where more than one rule in this specification is violated, and
where the processor therefore has discretion in deciding which error code to
associate with the condition: there is therefore no guarantee that different
processors will always use the same error code for the same erroneous
input.
Additional errors defined by an implementation (or by an application) may use QNames in an implementation-defined (or user-defined) namespace without risk of collision.
3 Stylesheet Structure
This section describes the overall structure of a stylesheet as a collection of XML documents.
3.1 XSLT Namespace
[Definition: The XSLT namespace
has the URI http://www.w3.org/1999/XSL/Transform. It is used to
identify elements, attributes, and other names that have a special meaning defined
in this specification.]
Note:
The 1999 in the URI indicates the year in which the URI was allocated
by the W3C. It does not indicate the version of XSLT being used, which is
specified by attributes (see 3.7 Stylesheet Element and 3.8 Simplified Stylesheet Modules).
XSLT processors must use the XML namespaces mechanism [Namespaces in XML] to recognize elements and attributes from this namespace. Elements from the XSLT namespace are recognized only in the stylesheet and not in the source document. The complete list of XSLT-defined elements is specified in D Element Syntax Summary. Implementations must not extend the XSLT namespace with additional elements or attributes. Instead, any extension must be in a separate namespace. Any namespace that is used for additional instruction elements must be identified by means of the extension instruction mechanism specified in 24.2 Extension Instructions.
This specification uses a prefix of xsl: for referring to elements in
the XSLT namespace. However, XSLT stylesheets are free to use any prefix, provided
that there is a namespace declaration that binds the prefix to the URI of the XSLT
namespace.
Note:
Throughout this specification, an element or attribute that is in no namespace, or an expanded QName whose namespace part is an empty sequence, is referred to as having a null namespace URI.
Note:
By convention, the names of XSLT
elements, attributes and functions are all lower-case;
they use hyphens to separate words, and they use abbreviations only if these already
appear
in the syntax of a related language such as XML or HTML. Names of types defined in
XML Schema are regarded as single words and are capitalized exactly as in XML
Schema. This sometimes leads to composite function names such as
current-dateTimeFO30.
3.2 Extension Attributes
[Definition: An element from the XSLT namespace may have any attribute not from the XSLT namespace, provided that the expanded QName (see [XPath 3.0]) of the attribute has a non-null namespace URI. These attributes are referred to as extension attributes.] The presence of an extension attribute must not cause the principal result or any secondary result of the transformation to be different from the results that a conformant XSLT 3.0 processor might produce. They must not cause the processor to fail to signal an error that a conformant processor is required to signal. This means that an extension attribute must not change the effect of any instruction except to the extent that the effect is implementation-defined or implementation-dependent.
Furthermore, if serialization is performed using one of the serialization methods described in [XSLT and XQuery Serialization], the presence of an extension attribute must not cause the serializer to behave in a way that is inconsistent with the mandatory provisions of that specification.
Note:
Extension attributes may be used to modify the behavior of extension functions and extension instructions. They may be used to select processing options in cases where the specification leaves the behavior implementation-defined or implementation-dependent. They may also be used for optimization hints, for diagnostics, or for documentation.
Extension attributes may also be
used to influence the behavior of the serialization methods xml,
xhtml, html, or text, to the extent that
the behavior of the serialization method is implementation-defined or implementation-dependent. For example, an extension attribute might
be used to define the amount of indentation to be used when
indent="yes" is specified. If a serialization method other than
one of these four is requested (using a prefixed QName in the method parameter)
then extension attributes may influence its behavior in arbitrary ways. Extension
attributes must not be used to cause the standard serialization methods to
behave in a non-conformant way, for example by failing to report serialization
errors that a serializer is required to report. An implementation that wishes to
provide such options must create a new serialization method for the purpose.
An implementation that does not recognize the name of an extension attribute, or that does not recognize its value, must perform the transformation as if the extension attribute were not present. As always, it is permissible to produce warning messages.
The namespace used for an extension attribute will be copied to the result tree in the normal way if it is in scope
for a literal result element.
This can be prevented using the [xsl:]exclude-result-prefixes
attribute.
The following code might be used to indicate to a particular implementation that
the xsl:message instruction is to ask the user for confirmation
before continuing with the transformation:
<xsl:message abc:pause="yes" xmlns:abc="http://vendor.example.com/xslt/extensions"> Phase 1 complete </xsl:message>
Implementations that do not recognize the namespace
http://vendor.example.com/xslt/extensions will simply ignore the
extra attribute, and evaluate the xsl:message instruction in the
normal way.
[ERR XTSE0090] It is a static error for an element from the XSLT namespace to have an attribute whose namespace is either null (that is, an attribute with an unprefixed name) or the XSLT namespace, other than attributes defined for the element in this document.
3.3 XSLT Media Type
The media type application/xslt+xml
has been registered for XSLT stylesheet
modules.
The definition of the media type is at [XSLT Media Type].
This media type should be used for an XML document containing a standard stylesheet module at its top level, and it may also be used for a simplified stylesheet module. It should not be used for an XML document containing an embedded stylesheet module.
3.4 Standard Attributes
[Definition: There are a number of
standard attributes that may appear on any XSLT element: specifically
default-collation, default-mode,
default-validation,
exclude-result-prefixes, expand-text, extension-element-prefixes,
use-when, version, and
xpath-default-namespace.]
These attributes may also appear on a literal result element, but in this case, to distinguish them from
user-defined attributes, the names of the attributes are in the XSLT namespace. They are thus typically written
as xsl:default-collation, xsl:default-mode, xsl:default-validation,
xsl:exclude-result-prefixes, xsl:expand-text,
xsl:extension-element-prefixes, xsl:use-when,
xsl:version, or xsl:xpath-default-namespace.
It is recommended that all these attributes should also be permitted on extension instructions, but this is at the discretion of the implementer of each extension instruction. They may also be permitted on user-defined data elements, though they will only have any useful effect in the case of data elements that are designed to behave like XSLT declarations or instructions.
In the following descriptions, these attributes are referred to generically as
[xsl:]version, and so on.
These attributes all affect the element they appear on, together with any elements and attributes that have that element as an ancestor. The two forms with and without the XSLT namespace have the same effect; the XSLT namespace is used for the attribute if and only if its parent element is not in the XSLT namespace.
In the case of [xsl:]default-collation, [xsl:]expand-text,
[xsl:]version, and [xsl:]xpath-default-namespace, the value
can be overridden by a different value for the same attribute appearing on a
descendant element. The effective value of the attribute for a particular stylesheet
element is determined by the innermost ancestor-or-self element on which the
attribute appears.
In an embedded stylesheet module, standard attributes appearing on ancestors of the outermost element of the stylesheet module have no effect.
In the case of [xsl:]exclude-result-prefixes and
[xsl:]extension-element-prefixes the values are cumulative. For these
attributes, the value is given as a whitespace-separated list of namespace prefixes,
and the effective value for an element is the combined set of namespace URIs
designated by the prefixes that appear in this attribute for that element and any
of
its ancestor elements. Again, the two forms with and without the XSLT namespace are
equivalent.
The effect of the [xsl:]use-when attribute is described in 3.13.1 Conditional Element Inclusion.
Because these attributes may appear on any XSLT
element, they are not listed in the syntax summary of each individual
element. Instead they are listed and described in the entry for the
xsl:stylesheet, xsl:transform, and xsl:package elements only. This
reflects the fact that these attributes are often used on the outermost element of the stylesheet, in which case they apply to
the entire stylesheet module
or package manifest.
Note that the effect of these attributes does not extend to stylesheet modules referenced by
xsl:include or xsl:import declarations, nor to packages referenced using
xsl:use-package.
For the detailed effect of each attribute, see the following sections:
-
[xsl:]default-collation -
[xsl:]default-mode -
[xsl:]default-validation -
see 25.4 Validation
-
[xsl:]exclude-result-prefixes -
[xsl:]expand-text -
[xsl:]extension-element-prefixes -
[xsl:]use-when -
[xsl:]version -
see 3.9 Backwards Compatible Processing and 3.10 Forwards Compatible Processing
-
[xsl:]xpath-default-namespace -
see 5.1.2 Unprefixed Lexical QNames in Expressions and Patterns
3.5 Packages
[Definition: An explicit package is
represented by an xsl:package element, which will generally be
the outermost element of an XML document. When the
xsl:package element is not used explicitly, the entire
stylesheet comprises a single implicit package.] (This
specification does not preclude the xsl:package being embedded in
another XML document, but it will never have any other XSLT element as an
ancestor).
<xsl:package
id? = id
name? = uri
package-version? = string
version = decimal
input-type-annotations? = "preserve" | "strip" | "unspecified"
declared-modes? = boolean
default-mode? = eqname | "#unnamed"
default-validation? = "preserve" | "strip"
default-collation? = uris
extension-element-prefixes? = prefixes
exclude-result-prefixes? = prefixes
expand-text? = boolean
use-when? = expression
xpath-default-namespace? = uri >
<!-- Content: ((xsl:expose | declarations)*) -->
</xsl:package>
[Definition: The content of the
xsl:package element is referred to as the package
manifest].
The version attribute indicates the
version of the XSLT language specification to which the package manifest conforms.
The value should normally be
3.0. If the value is numerically less than 3.0, the
content of the xsl:package element is processed using the rules
for backwards compatible
behavior (see 3.9 Backwards Compatible Processing). If the value is
numerically greater than 3.0, it is processed using the rules for
forwards compatible behavior (see 3.10 Forwards Compatible Processing).
A package typically has a name, given in its name
attribute, which must be an absolute URI. Unnamed packages are
allowed, but they can only be used as the “top level” of an application; they cannot
be the target of an xsl:use-package declaration in another
package.
A package may have a version identifier, given in
its package-version attribute. This is used to distinguish different
versions of a package. The value of the version
attribute, after trimming leading and trailing whitespace, must
conform to the syntax given in 3.5.1 Versions of a Package. If no version
number is specified for a package, version 1 is assumed.
The attributes default-collation, default-mode, default-validation,
exclude-result-prefixes, expand-text,
extension-element-prefixes, use-when,
version, and xpath-default-namespace are standard
attributes that can appear on any XSLT element, and potentially affect all descendant
elements. Their meaning is described in 3.4 Standard Attributes.
The package manifest contains the following elements, arbitrarily ordered:
-
Zero or more
xsl:exposedeclarations that define the interface offered by this package to the outside world. Anxsl:exposedeclaration may appear only as a child ofxsl:package. -
Zero or more additional declarations. These are the same as the declarations permitted as children of
xsl:stylesheetorxsl:transform.Some declarations of particular relevance to packages include:
-
The
xsl:use-packagedeclaration, which declares the names and versions of the packages on which this package is dependant. -
The optional
xsl:global-context-itemelement; if present this element defines constraints on the existence and type of the global context item. -
Zero or more
xsl:includeandxsl:importdeclarations, which define additional stylesheet modules to be incorporated into this package. -
Zero or more ordinary declarations, that is, elements that are permitted as children of
xsl:stylesheetorxsl:transform. One possible coding style is to include in the package manifest just a singlexsl:importorxsl:includedeclaration as a reference to the effective top-level stylesheet module; this approach is particularly suitable when writing code that is required to run under earlier releases of XSLT as well as under XSLT 3.0. Another approach is to include the substance of the top-level stylesheet module inline within the package manifest.
-
The following example shows a package that offers a number of functions for manipulating complex numbers. A complex number is represented as a map with two entries, the keys being 0 for the real part, and 1 for the imaginary part.
<xsl:package name="http://example.org/complex-arithmetic.xsl" package-version="1.0" version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="http://example.org/complex-arithmetic.xsl"> <xsl:function name="f:complex-number" as="map(xs:integer, xs:double)" visibility="public"> <xsl:param name="real" as="xs:double"/> <xsl:param name="imaginary" as="xs:double"/> <xsl:sequence select="map{ 0:$real, 1:$imaginary }"/> </xsl:function> <xsl:function name="f:real" as="xs:double" visibility="public"> <xsl:param name="complex" as="map(xs:integer, xs:double)"/> <xsl:sequence select="$complex(0)"/> </xsl:function> <xsl:function name="f:imag" as="xs:double" visibility="public"> <xsl:param name="complex" as="map(xs:integer, xs:double)"/> <xsl:sequence select="$complex(1)"/> </xsl:function> <xsl:function name="f:add" as="map(xs:integer, xs:double)" visibility="public"> <xsl:param name="x" as="map(xs:integer, xs:double)"/> <xsl:param name="y" as="map(xs:integer, xs:double)"/> <xsl:sequence select=" f:complex-number( f:real($x) + f:real($y), f:imag($x) + f:imag($y))"/> </xsl:function> <xsl:function name="f:multiply" as="map(xs:integer, xs:double)" visibility="public"> <xsl:param name="x" as="map(xs:integer, xs:double)"/> <xsl:param name="y" as="map(xs:integer, xs:double)"/> <xsl:sequence select=" f:complex-number( f:real($x)*f:real($y) - f:imag($x)*f:imag($y), f:real($x)*f:imag($y) + f:imag($x)*f:real($y))"/> </xsl:function> <!-- etc. --> </xsl:package>
A more complex package might include private or abstract functions as well as
public functions; it might expose components other than functions (for example,
templates or global variables), and it might contain
xsl:use-package elements to allow it to call on the services
of other packages.
Note:
In this example, the way in which complex numbers are represented is exposed to
users of the package. It would be possible to hide the representation by
declaring the types on public functions simply as item(); but this
would be at the cost of type safety.
A package that does not itself expose any components may be written
using a simplified syntax: the xsl:package element is omitted, and
the xsl:stylesheet or xsl:transform element is now
the outermost element of the stylesheet module. For compatibility reasons, all the
named templates and modes declared in the package are made public. More formally,
the
principal stylesheet module of the top-level
package may be expressed as an xsl:stylesheet or
xsl:transform element, which is equivalent to the package represented
by the output of the following transformation, preserving the base URI of the
source:
<xsl:transform version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://www.w3.org/1999/XSL/TransformAlias"> <xsl:namespace-alias stylesheet-prefix="t" result-prefix="xsl"/> <xsl:template match="xsl:stylesheet|xsl:transform"> <t:package declared-modes="no"> <xsl:copy-of select="@*"/> <t:expose component="mode" names="*" visibility="public"/> <t:expose component="template" names="*" visibility="public"/> <xsl:copy-of select="node()"/> </t:package> </xsl:template> </xsl:transform>
The effect of the input-type-annotations
attribute is defined in 4.4.1 Stripping Type Annotations from a Source Tree.
A more extensive example of a package, illustrating how components in a package can be overridden in a client package, is given in 3.5.7 Worked Example of a Library Package.
3.5.1 Versions of a Package
If a package has a version number, the version number must conform to the grammar:
PackageVersion ::= NumericPart ( "-" NamePart )?
NumericPart ::= IntegerLiteral ( "." IntegerLiteral )*
NamePart ::= NCName
Here IntegerLiteralXP30 and NCName are as defined in
the XPath 3.0 grammar productions of the same name (including rules on
limits). Leading and trailing whitespace is ignored; no other
whitespace is allowed.
Examples of valid version numbers are 2.0.5 or
3.10-alpha.
[Definition: The integer literals and the optional
NamePart within the version number are referred to as the
portions of the version number.]
Note:
This means that 1-alpha-2 is a valid version number, with two
portions: 1 and
alpha-2. The second hyphen is part of the NCName,
it does not act as a portion separator.
Versions are ordered. When comparing two versions:
-
Trailing zero portions (that is, any zero-valued integer that is not followed by another integer) are discarded.
-
Comparison proceeds by comparing portions pairwise from the left.
-
If both versions have the same number of portions and all portions compare equal (under the rules of the XPath
eqoperator using the Unicode codepoint collation), then the versions compare equal. -
If the number of portions in the two versions V1 and V2 is N1 and N2, with N1<N2, and if all portions in positions 1 to N compare equal, then V1 is less than V2 if the portion of V2 in position N1 is an integer, and is greater than V2 if this portion is an
NCName. For example,1.2is less than1.2.5, while2.0is greater than2.0-rc1. -
Portions are compared as follows:
-
If both portions are integers, they are compared using the rules of XPath value comparisons.
-
If both portions are NCNames, they are compared using the rules of XPath value comparisons, using the Unicode Codepoint Collation.
-
If one portion is an integer and the other is an
NCName, theNCNamecomes first.
-
For example, the following shows a possible ordered sequence of version numbers:
0-rc1 < 0-rc2 < 0 < 1 = 1.0 < 1.0.2 < 1.0.3-rc1 < 1.0.3 < 1.0.3.2 < 1.0.10
Note:
The version number format defined here is designed to be general enough to accommodate a variety of conventions in common use, and to allow useful semantics for matching of versions and ranges of versions, without being over-prescriptive. It is influenced by [SemVer], but is not as prescriptive, and it imposes no assumptions about backwards compatibility of packages between successive versions.
Implementations may impose limits on the values used in a version number (or a version range: see below). Such limits are implementation-defined. As a minimum, a processor must accept version numbers including:
-
A numeric part containing four integers;
-
Each integer being in the range 0 to 999999;
-
An
NCNameof up to 100 characters
Dependencies between packages may specify a version range (see 3.5.2 Dependencies between Packages). A version range represents a set of accepted versions. The syntax of a version range is shown below. Whitespace is permitted only where indicated, using the terminal symbol S.
PackageVersionRange ::= AnyVersion | VersionRanges
AnyVersion ::= "*"
VersionRanges ::= VersionRange (S? "," S? VersionRange)*
VersionRange ::= PackageVersion | VersionPrefix |
VersionFrom | VersionTo | VersionFromTo
VersionPrefix ::= PackageVersion ".*"
VersionFrom ::= PackageVersion "+"
VersionTo ::= "to" S (PackageVersion | VersionPrefix)
VersionFromTo ::= PackageVersion S "to" S (PackageVersion | VersionPrefix)
The meanings of the various forms of version range are defined below:
-
The range
AnyVersionmatches any version. -
The range
VersionRangesmatches a version if any constituentVersionRangematches that version.For example,
9.5.0.8, 9.6.1.2matches those specific versions only, while9.5.0.8, 9.6+matches either version 9.5.0.8 or any version from 9.6 onwards. -
A range that is a
PackageVersionmatches that version only. -
The range
VersionPrefixmatches any version whose leading portions are the same as the portions in thePackageVersionpart of theVersionPrefix.For example,
1.3.*matches1.3,1.3.5,1.3.10.2, and1.3-beta(but not1or1.4).Note:
The
.*indicates that additional portions may follow; it does not indicate a substring match on the final portion. So1.3.*does not match1.35, and3.3-beta.*does not match3.3-beta12. Also,3.3-beta.*does not match3.3-beta.5: this is because the last dot is not a portion separator, but is part of the finalNCName. In fact, using.*after a version number that includes anNCNameportion is pointless, because anNCNameportion can never be followed by further portions. -
The range
VersionFrommatches any version that is greater than or equal to the version supplied.For example
1.3+matches1.3,1.3.2,1.4, and2.1(but not1.3-betaor1.2). And1.3-beta+matches1.3-beta,1.3-gamma,1.3.0,1.4, and8.0, but not1.3-alphaor1.2. -
The range
VersionTomatches any version that is less than or equal to some version that matches theVersionPrefix.For example,
to 4.0matches1.5,2.3,3.8,4.0, and4.0-beta(but not4.0.1), whileto 3.3.*matches1.5or2.0.6or3.3.4621, but not3.4.0or3.4.0-beta. -
The range
VersionFromTomatches any version that is greater than or equal to the startingPackageVersion, and less than or equal to some version that matches theVersionPrefix.For example,
1 to 5matches1.1,2.1,3.1, or5.0(but not5.1), while1 to 5.*matches all of these, plus versions such as5.7.2(but not6.0or6.0-beta). Similarly,1.0-beta to 1.0matches1.0-beta,1.0-beta.2,1.0-gamma, and1.0, but not1.0-alphaor1.0.1.
3.5.2 Dependencies between Packages
When components in one package reference components in another, the dependency of the first
package on the second must be represented by an xsl:use-package
element. This may appear in the principal stylesheet module
of the first package (which may be a package manifest), or
it may appear in a stylesheet module that is referenced from
the principal stylesheet module via one or more
xsl:include declarations; however it must not be referenced
via xsl:import declarations (this is to avoid complications
caused by multiple xsl:use-package declarations with
different import precedence).
[Definition: If a package Q contains an
xsl:use-package element that references package
P, then package Q is said to use package
P. In this relationship package Q is referred to as
the using package, package P as the used
package.]
The phrase directly uses is synonymous with uses as defined above, while directly or indirectly uses refers to the transitive closure of this relationship.
<!-- Category: declaration -->
<xsl:use-package
name = uri
package-version? = string >
<!-- Content: (xsl:accept | xsl:override)* -->
</xsl:use-package>
A package may be used by more than one other package, but the relationship must not be cyclic. It is possible, but by no means inevitable, that using the same package in more than one place within a stylesheet will cause static errors due to the presence of conflicting components according to the above rules. Where a package is successfully used by more than one other package, its components may be overridden in different ways by different using packages.
The name and package-version attributes together
identify the used package. The value of the
package-version attribute, if present, must conform to the
rules for a PackageVersionRange given in 3.5.1 Versions of a Package; if omitted the value * is assumed,
which matches any version. The used package must have a name that is an exact
match for the name in the name attribute (using codepoint
comparison), and its explicit or implicit package-version must
match the version range given in the package-version
attribute.
This specification does not define how the implementation locates a package given its name and version. If several matching versions of a package are available, it does not define which of them is chosen. Nor does it define whether this process locates source code or some other representation of the package contents. Such mechanisms are implementation-defined. Use of the package name as a dereferenceable URI is not recommended, because the intent of the packaging feature is to allow a package to be distributed as reusable code and therefore to exist in many different locations.
[ERR XTSE3000] It is a static error if no package matching the package
name and version specified in an xsl:use-package
declaration can be located.
[ERR XTSE3005] It is a static error if a package is dependent on
itself, where package A is defined as being dependent on package
B if A contains an xsl:use-package
declaration that references B, or if A contains an
xsl:use-package declaration that references a package
C that is itself dependent on B.
[ERR XTSE3008] It is a static error if an xsl:use-package
declaration appears in a stylesheet module that is not in the
same stylesheet level as the principal stylesheet module
of the package.
Note:
Depending on the implementation architecture, there may be a need to locate used packages both during static analysis (for example, to get information about the names and type signatures of the components exposed by the used package), and also at evaluation time (to link to the implementation of these components so they can be invoked). A failure to locate a package may cause an error at either stage.
The xsl:accept and xsl:override elements are
used to modify the visibility or behavior of components acquired from the used
package; they are described in 3.5.3.2 Accepting Components below.
Note:
It is not intrinsically an error to have two
xsl:use-package declarations that identify the same package
(or different versions of the same package). This has the same effect as
having two declarations that identify packages with different names but
identical content. In most cases it will result in an error ([see ERR XTSE3050])
due to the presence of multiple components with the same name; but
no error would occur, for example, if the used package is empty, or if the
two xsl:use-package declarations use xsl:accept
to accept non-overlapping subsets of the components in the used package.
3.5.3 Named Components in Packages
This section discusses the use of named components in packages.
The components which can be declared in one package and referenced in another are: functions, named templates, attribute sets, modes, and global variables and parameters.
In addition, keys and accumulators are classified as named components because they can contain references to components in another package, even though they cannot themselves be referenced from outside the package.
Named and unnamed modes come within the scope of this section, but there are differences noted in 3.5.4 Overriding Template Rules from a Used Package.
Not all declarations result in components:
-
Named declarations that can neither be referenced from outside their containing package, nor can contain references to components in other packages (examples are
xsl:output,xsl:character-map, andxsl:decimal-format) are not considered to be components and are therefore outside the scope of this section. -
Some declarations, such as
xsl:decimal-formatandxsl:strip-space, declare aspects of the processing context which are not considered to be components as defined here. -
Template rules (
xsl:templatewith amatchattribute) are also not considered to be components for the purposes of this section, which is concerned only with components that are bound by name. However, when anxsl:templatehas both amatchattribute and anameattribute, then it establishes both a template rule and a named template, and in its role as a named template it comes within the scope of this discussion. -
A named declaration, for example a named template, a function, or a global variable, may be overridden within the same package by another like-named declaration having higher import precedence. When a declaration is overridden in this way it cannot be referenced by name either from within its containing package or from outside that package.
-
In the case of
xsl:attribute-setandxsl:keydeclarations, several declarations combine to form a single component.
The section is largely concerned with details of the rules that affect references from one component to another by name, whether the components are in the same package or in different packages. The rules are designed to meet a number of requirements:
-
A component defined in one package can be overridden by a component in another package, provided the signatures are type-compatible.
-
The author of a package can declare whether the components in the package are public or private (that is, whether or not they can be used from outside the package) and whether they are final, overridable, or abstract (that is whether they can or must be overridden by the using package).
-
Within an application, two packages can make use of a common library and override its components in different ways.
-
Visibility of components can be defined either as part of the declaration of the component, or in the package manifest.
-
An application that wishes to make use of a library package can be selective about which components from the library it acquires, perhaps to avoid name clashes between components acquired from different libraries.
[Definition: The term component is used to refer to any of the following: a stylesheet function, a named template, a mode, an accumulator, an attribute set, a key, global variable, or a mode.]
[Definition: The symbolic identifier of a component is a composite name used to identify the component uniquely within a package. The symbolic identifier comprises the kind of component (stylesheet function, named template, accumulator, attribute set, global variable, key, or mode), the expanded QName of the component (namespace URI plus local name), and in the case of stylesheet functions, the arity.]
Note:
In the case of the unnamed mode, the expanded QName of the component may be considered to be some system-allocated name different from any user-defined mode name.
[Definition: Two components are said to be homonymous if they have the same symbolic identifier.]
Every component has a declaration in some stylesheet module and therefore within some package. In the case of attribute sets and keys, there may be several declarations. The declaration is an element in an XDM tree representing the stylesheet module. Declarations therefore have identity, based on XDM node identity.
[Definition: The declaring
package of a component is the
package that contains the declaration (or,
in the case of xsl:attribute-set and
xsl:key, multiple declarations) of the
component.]
When a component declared in one package is made available in another, the using package will contain a separate component that can be regarded as a modified copy of the original. The new component shares the same symbolic identifier as the original, and it has the same declaration, but it has other properties such as its visibility that may differ from the original.
[Definition: A
component declaration results in multiple components, one in the package in
which the declaration appears, and potentially one in each package that uses
the declaring package, directly or indirectly, subject to the visibility of the
component. Each of these multiple components has the same declaring package, but each has a different containing
package. For the original component, the declaring package and the
containing package are the same; for a copy of a component made as a result of
an xsl:use-package declaration, the declaring package will be
the original package, and the containing package will be the package in which
the xsl:use-package declaration appears.]
Note:
Within this specification, we generally use the notation CP for a component named C whose declaring package and containing package are both P; and the notation CPQ for a component whose containing package is P and whose declaring package is Q (that is, a component in P that is derived from a component CQ in the used package Q).
The properties of a component are as follows:
-
The original declaration of the component.
-
The package to which the component belongs (called its containing package, not to be confused with the declaring package).
-
The symbolic identifier of the component.
-
The visibility of the component, which determines the way in which the component is seen by other components within the same package and within using packages. This is one of
public,private,abstract,final, orhidden. The visibility of components is discussed further in 3.5.3.1 Visibility of Components. -
A set of bindings for the symbolic references in the component. The way in which these bindings are established is discussed further in 3.5.3.5 Binding References to Components.
Note:
When a function F defined in a package P is acquired by two using packages Q and R, we may think of P, Q, and R as all providing access to the “same” function. The detailed semantics, however, demand an understanding that there is one function declaration, but three components. The three components representing the function F within packages P, Q, and R have some properties in common (the same symbolic identifier, the same declaration), but other properties (the visibility and the bindings of symbolic references) that may vary from one of these components to another.
[Definition: The declaration of a component includes
constructs that can be interpreted as references to other components by means of their symbolic identifiers. These
constructs are generically referred to as symbolic references.
Examples of constructs that give rise to symbolic references are the
name attribute of xsl:call-template; the
[xsl:]use-attribute-sets attribute of
xsl:copy, xsl:element, and literal result elements; the
explicit or implicit
mode attribute of xsl:apply-templates; XPath
variable references referring to global variables; XPath static function calls (including partial function
applications) referring to stylesheet functions; and
named function references (example: my:f#1) referring to
stylesheet functions.
]
Symbolic references exist as properties of the declaration of a component.
The symbolic identifier being
referred to can be determined straightforwardly from the syntactic form and
context of the reference: for example, the instruction <xsl:value-of
select="f:price($o)" xmlns:f="http://f.com/"/> contains a symbolic
reference to a function with expanded name {http://f.com/}price and
with arity=1. However, because there may be several (homonymous) function
components with this symbolic identifier, translating this symbolic reference into
a reference to a specific component (a process called “binding”) is less
straightforward, and is described in the text that follows.
The process of assembling a stylesheet from its constituent packages is primarily a process of binding these symbolic references to actual components. Within any component whose declaration is D, there is a set of bindings; each binding is an association between a symbolic reference in D and a component whose symbolic identifier matches the outward reference. Outward references for which a component C contains a binding are said to be bound in C; those for which C contains no binding are said to be unbound.
For example, suppose that in some package Q, function A
calls B, which in turn calls C, and that B is
private. Now suppose that in some package P which uses
Q, C is overridden. The effect of the binding process is
that P will contain three components corresponding to A,
B, and C, which we might call AP,
BP, and CP. The declarations of AP and BP are in package
Q, but the declaration of CP is in P. The
internal visibility of BP will be hidden (meaning that it
cannot be referenced from within P), and BP will contain a
binding for the component CP that corresponds to the outward reference
from B to C. The effect is that when A calls
B and B calls C, it is the overriding version
of C that is executed.
In another package R that uses Q without overriding C, there will be three different components AR, BR, and CR. This time the declaration of all three components is in the original package Q. Component BR will contain a binding to CR, so in this package, the original version of C is executed. The fact that one package P overrides C thus has no effect on R, which does not override it.
The binding process outlined above is described in more detail in 3.5.3.5 Binding References to Components.
Template rules are not components in their own right; unlike named templates, they are never referenced by name. Component references within a template rule (for example, references to functions, global variables, or named templates) are treated as occurring within the component that represents the containing mode. This includes component references within the match patterns of template rules. If a template rule lists several modes, it is treated as if there were multiple template rules one in each mode.
An xsl:apply-templates instruction
with no mode attribute is treated as a reference to the default mode
defined for that instruction (see 3.7.2 The default-mode Attribute), which in turn defaults to the unnamed mode. An implicit
reference to the unnamed made is treated in the same way as any other symbolic reference. Note that there is an unnamed mode in every
package, and the unnamed mode always has private visibility.
Where an xsl:template element has both
a name and a match attribute, it is treated as if there
were two separate xsl:template elements, one with a
name attribute and one with a match attribute.
Keys
and accumulators behave rather differently from other
components. Their visibility is always private, which means they can only be used
within their declaring package. In addition, the component binding is generally
made dynamically rather than statically, by
virtue of a string passed as an argument to the function
key, accumulator-before, or
accumulator-after. (In the case of accumulators, there
can also be static references: see the use-accumulators attribute
of xsl:source-document,
xsl:merge-source, and xsl:mode.)
However, outward references from key
definitions and accumulators to other components (such as global
variables and functions) behave in the same way as component references contained
in any other private component, in that they may be re-bound to an overriding
declaration of the target component.
3.5.3.1 Visibility of Components
[Definition: The visibility of a
component is one of:
private, public, abstract,
final, or hidden.]
The meanings of these visibility values is as follows:
- public
-
The component can be referenced from other components in this package or in any using package; it can be overridden by a different component in any using package.
- private
-
The component can be referenced from other components in this package; it cannot be referenced or overridden within a using package.
- abstract
-
The component can be referenced from other components in this package or in any using package; in a using package it can either remain abstract or be overridden by a different component.
- final
-
The component can be referenced from other components in this package or in any using package; it cannot be overridden by a different component in any using package.
- hidden
-
The component cannot be referenced from other components in this package; it cannot be referenced or overridden within a using package.
Note:
The visibility of a component in a package P primarily affects
how the component can be used in other packages, specifically, packages that
use P. There is one exception: if the visibility is
hidden, it also affects how the component can be used within
P.
When a component is declared within a particular
package, its visibility, which affects
how it can be used in other (using) packages, depends on two factors: the value
of the visibility declaration on the declaration itself (if
present), and the rules given in the xsl:expose declarations
of the package manifest.
The xsl:function, xsl:template,
xsl:attribute-set, xsl:variable,
and
xsl:mode
declarations each have an optional
visibility attribute. The value is one of private,
public, abstract, or final (never
hidden). In the case of
an xsl:param element there is no explicit
visibility attribute; rather the declaration has the
implicit attribute visibility="public".
Any xsl:expose declarations that
appear as children of xsl:package define the visibility of
components whose declaration has no explicit visibility attribute,
and can also be used to reduce the visibility of components where this
attribute is present.
<xsl:expose
component = "template" | "function" | "attribute-set" | "variable" | "mode" | "*"
names = tokens
visibility = "public" | "private" | "final" | "abstract" />
The xsl:expose element allows the visibility of selected components within a package to be defined.
The components in question are identified using their symbolic identifiers. The
component attribute defines the kind of component that is
selected.
The value * means “all component kinds”;
in this case the value of the names attribute must be a WildcardXP30.
An xsl:expose declaration has no effect on the
unnamed mode, which is always private to a package.
The names attribute selects a subset of these components by name
(and in the case of functions, arity); its value is a whitespace-separated
sequence of tokens each of which is either a NameTestXP30 or a NamedFunctionRefXP30. (Examples are
*, p:*, *:local,
p:local, and p:local#2.)
The value may be a NamedFunctionRef only in the case of stylesheet
functions, and distinguishes functions with the same name and different
arity.
The visibility of a named template, function, variable, attribute set, or mode declared within a package is the first of the following that applies, subject to consistency constraints which are defined below:
-
The visibility of a variable declared using an
xsl:paramelement is alwayspublic. Noxsl:exposeelement ever matches anxsl:paramcomponent.Note:
Attempting to match an
xsl:paramwith an explicitEQNamewill therefore always give an error, while using a wildcard has no effect. -
If the package manifest contains an
xsl:exposeelement that matches this component by virtue of an explicitEQNameorNamedFunctionRef(that is, not by virtue of a wildcard match), then the value of thevisibilityattribute of the last suchxsl:exposeelement in document order (call this the explicit exposed visibility). -
If the declaration of the component has a
visibilityattribute, then the value of this attribute (call this the declared visibility). -
If the package manifest contains an
xsl:exposeelement that matches this component by virtue of a wildcard match that specifies either the namespace part of the component name or the local part of the name (for example,prefix:*or*:localorQ{uri}*), then the value of thevisibilityattribute of the last suchxsl:exposeelement in document order. -
If the package manifest contains an
xsl:exposeelement that matches this component by virtue of a wildcard match that matches all names (that is,*), then the value of thevisibilityattribute of the last suchxsl:exposeelement in document order. -
Otherwise,
private.
Note:
In the above rules, no distinction is made between declarations that specify
a specific component kind, and those that specify component="*". If both match,
the value of the component attribute plays no role in deciding which
declaration wins.
If both a declared visibility and an explicit
exposed visibility exist for the same component, then as mentioned above, they
must be consistent. This is determined by reference to the following table,
where the entry N/P means “not permitted”. (In cases where the combination is
permitted, the actual visibility is always the same as the visibility
determined by xsl:expose.)
| Explicit exposed visibility | Declared visibility | |||
|---|---|---|---|---|
| public | private | final | abstract | |
| public | public | N/P | N/P | N/P |
| private | private | private | private | N/P |
| final | final | N/P | final | N/P |
| abstract | N/P | N/P | N/P | abstract |
[ERR XTSE3010] It is a static error if the
explicit exposed visibility of a component is inconsistent with its
declared visibility, as defined in the above table. (This error occurs
only when the component declaration has an explicit
visibility attribute, and the component is also listed
explicitly by name in an xsl:expose declaration.)
[ERR XTSE3020] It is a static error if a token
in the names attribute of xsl:expose, other
than a wildcard, matches no component in the containing package.
[ERR XTSE3022] It is a static error if the
component attribute of xsl:expose specifies *
(meaning all component kinds) and the names attribute is not a wildcard.
Note:
There is no ambiguity, and no error, if several tokens within the same
xsl:expose element match the same component.
If the visibility of a component as established by the above rules
is abstract, then the component must have a declared visibility of abstract.
Note:
In other words, the xsl:expose declaration cannot be used to make a component
abstract unless it was declared as abstract to start with.
[ERR XTSE3025] It is a static error if the
effect of an xsl:expose declaration would be to make a component
abstract, unless the component is already abstract
in the absence of the xsl:expose declaration.
For a component accepted into a package P
from another package Q, the visibility of the component in P (which primarily
affects how it can be used in a package R that uses P)
depends on the visibility declared in the relevant xsl:accept
or xsl:override element in P (see 3.5.3.2 Accepting Components); this in turn has a default that depends on
the visibility of the corresponding component in Q. In this case the
visibility is unaffected by any xsl:expose declaration in
P.
3.5.3.2 Accepting Components
When a package P uses a package Q, by virtue of an
xsl:use-package element in the package manifest of P, then
P will contain a component
corresponding to every component in Q. The visibility of the component within
P depends on the visibility of the component in Q, optionally modified
by two elements that may appear as children of the
xsl:use-package element, namely xsl:accept
and xsl:override.
For every component CQ in package Q that is not matched
by any xsl:override or xsl:accept element in
the package manifest of P, there will be a corresponding component
CP in package P that has the same symbolic identifier and declaration as CQ.
If CQ is an xsl:param
component, then the visibility of CP is
public.
In other cases, the visibility of CP depends on the visibility of CQ, as defined by the following table:
| Visibility in used package CQ | Visibility in using package CP |
|---|---|
| public | private |
| final | private |
| private | hidden |
| hidden | hidden |
| abstract | hidden |
Note:
The effect of these rules is as follows:
-
Components that are public or final in the used package Q become private in the using package P. This means that they can be referenced within P but are not (by default) visible within a package R that uses P.
-
Components that are private or hidden in the used package Q become hidden in the using package P. This means that they cannot be referenced within P; but if they contain references to components that are overridden in P, the hidden component’s references are bound to the overriding components in P.
-
Components that are abstract in the used package Q become hidden in the using package P. The hidden component in this case raises a dynamic error if it is invoked. Such an invocation cannot originate within P, because the component is not visible within P; but it can occur if a public component in Q is invoked, which in turn invokes the abstract component.
<xsl:accept
component = "template" | "function" | "attribute-set" | "variable" | "mode" | "*"
names = tokens
visibility = "public" | "private" | "final" | "abstract" | "hidden" />
The xsl:accept element has very similar syntax and semantics
to xsl:expose. Whereas xsl:expose allows a
package to restrict the visibility of its own components to other (using)
packages, xsl:accept allows a package to restrict the
visibility of components exposed by a package that it uses. This may be
necessary if, for example, it uses two different packages whose component names
conflict. It may also simply be good practice if the package author knows that
only a small subset of the functionality of a used package is required.
The rules for determining whether an xsl:accept element
matches a particular component, and for which element to use if there are
several matches, are the same as the rules for the xsl:expose
element.
No xsl:accept element
ever matches a variable declared using xsl:param.
Note:
Attempting to match an xsl:param with
an explicit EQName will therefore always give an error, while
using a wildcard has no effect.
[ERR XTSE3030] It is a static error if a token
in the names attribute of xsl:accept, other
than a wildcard, matches no component in the used package.
[ERR XTSE3032] It is a static error if the
component attribute of xsl:accept specifies *
(meaning all component kinds) and the names attribute is not a wildcard.
In the absence of a matching xsl:override element (see
3.5.3.3 Overriding Components from a Used Package), the visibility of a component that matches an
xsl:accept element depends both on the
visibility attribute of the best-matching
xsl:accept element and on the visibility of the corresponding component in the used package,
according to the following table. In this table the entry “N/P” means “not
permitted”.
Visibility in xsl:accept element
|
Visibility in used package | |||
|---|---|---|---|---|
| public | private | final | abstract | |
| public | public | N/P | N/P | N/P |
| private | private | N/P | private | N/P |
| final | final | N/P | final | N/P |
| abstract | N/P | N/P | N/P | abstract |
| hidden | hidden | N/P | hidden | hidden |
[ERR XTSE3040] It is a static error if the
visibility assigned to a component by an xsl:accept
element is incompatible with the visibility of the corresponding
component in the used package, as defined by the above table, unless the
token that matches the component name is a wildcard, in which case the
xsl:accept element is treated as not matching that
component.
[ERR XTSE3050] It is a static error if the
xsl:use-package elements in a package manifest cause two or more
homonymous components to be
accepted with a visibility other than hidden.
Conflicts between the components accepted from used packages and those declared within the package itself are handled as follows:
-
If the conflict is between two components both declared within the package itself, then it is resolved by the rules relating to import precedence defined for each kind of component.
-
If the conflict is between two components both accepted from used packages, or between a component declared within the package and an accepted component, then a static error occurs.
-
If a component is explicitly accepted from a used package (by name, rather than by a matching wildcard), and if the same component is the subject of an
xsl:overridedeclaration, then a static error occurs (see below). There is no conflict, however, if a component declared withinxsl:overridealso matches a wildcard in anxsl:acceptelement.[ERR XTSE3051] It is a static error if a token in the
namesattribute ofxsl:accept, other than a wildcard, matches the symbolic name of a component declared within anxsl:overridechild of the samexsl:use-packageelement.
Where the used package Q contains a component whose
visibility is abstract, the using package P has three options:
-
P can accept the component with
visibility="abstract". In this case P can contain references to the component, but invocation via these references will fail unless a non-abstract overriding component has been supplied in some package R that (directly or indirectly) uses P. -
P can accept the component with
visibility="hidden". In this case P cannot contain references to the component, and invocation via references in Q will always fail with a dynamic error. This is the default if P does not explicitly accept or override the component. -
P can provide a concrete implementation of the component within an
xsl:overrideelement.
Any invocation of the absent component (typically from within its declaring package) causes a dynamic error, as if the component were overridden by a component that unconditionally raises a dynamic error.
[ERR XTDE3052] It is a dynamic error if an invocation of an abstract component is evaluated.
Note:
This can occur when a public component in the used package invokes
an abstract component in the used package, and the using package provides
no concrete implementation for the component in an xsl:override
element.
Note:
To override a component accepted from a used package, the overriding
declaration must appear as a child of the xsl:override
element.
Note:
There is no rule that prevents a function (say) being declared in the using
package with the same name as a private function in the used
package. This does not create a conflict, since all references in the used
package are bound to one function and all those in the using package are
bound to another.
3.5.3.3 Overriding Components from a Used Package
[Definition: A component in a using package may
override a component in a used package, provided that the
visibility of the component in the
used package is either abstract or public. The
overriding declaration is written as a child of the
xsl:override element, which in turn appears as a child
of xsl:use-package.]
<xsl:override>
<!-- Content: (xsl:template | xsl:function | xsl:variable | xsl:param | xsl:attribute-set)* -->
</xsl:override>
Note:
This mechanism is distinct from the mechanism for overriding declarations within the same package by relying on import precedence. It imposes stricter rules: the overriding component is required to be type-compatible with the component that it overrides.
If the used package Q contains a component
CQ and the xsl:use-package element contains an
xsl:override element which contains a declaration
D whose symbolic
identifier matches the symbolic identifier of CQ, then
the using package P will contain a component CP whose
declaration is D, whose symbolic identifier is that of D, and whose visibility is equal to the value of the visibility
attribute of D, or private if this is absent,
except in the case
of xsl:param, which is implicitly
public.
The using package P will also contain a component CPQ
whose body is the same as the body of CQ and whose visibility is hidden. This
component is used as the target of a binding for the symbolic reference
xsl:original described below.
Other than its appearance as a child of xsl:override, the
overriding declaration is a normal xsl:function,
xsl:template, ,
xsl:variable, xsl:param, or
xsl:attribute-set element. In the case of
xsl:variable and xsl:param, the variable
that is declared is a global
variable.
The rules in the remainder of this section apply to
components having a name attribute (named
components). The only element with no name attribute that
can appear as a child of xsl:override is an
xsl:template declaration having a match
attribute (that is, a template rule). The rules for
overriding of template rules appear in 3.5.4 Overriding Template Rules from a Used Package. If
an xsl:template element has both a name attribute
and a match attribute, then it defines both a named component and
a template rule, and both sections apply.
[ERR XTSE3055] It is a static error if a
component declaration appearing as a child of
xsl:override is homonymous with any other declaration in the using package,
regardless of import
precedence, including any other overriding declaration in
the package manifest of the using package.
Note:
When an attribute set is overridden, the
overriding attribute set must be defined using a single
xsl:attribute-set element. Attribute sets defined in
different packages are never merged by virtue of having the same name,
though they may be merged explicitly by using the
use-attribute-sets attribute.
[ERR XTSE3058] It is a static error if a
component declaration appearing as a child of
xsl:override does not match (is not homonymous with) some component in the
used package.
[ERR XTSE3060] It is a static error if the
component referenced by an xsl:override declaration has
visibility other than
public or abstract
A package is executable if and only if it contains no component whose visibility is abstract. A package that is not
executable is not a stylesheet, and
therefore cannot be nominated as the stylesheet to be used when initiating a
transformation.
Note:
In other words, if a component is declared as abstract, then some package that uses the declaring package of that component directly or indirectly must override that component with one that is not abstract. It is not necessary for the override to happen in the immediately using package.
[ERR XTSE3070] It is a static error if the signature of an overriding component is not compatible with the signature of the component that it is overriding.
[Definition: The signatures of two components are compatible if they present the same interface to the user of the component. The additional rules depend on the kind of component.]
Compatibility is only relevant when comparing two components that have the same symbolic identifier. The compatibility rules for each kind of component are as follows:
-
Two attribute sets with the same name are compatible if and only if they satisfy the following rule:
-
If the overridden attribute set specifies
streamable="yes"then the overriding attribute set also specifiesstreamable="yes".
-
-
Two functions with the same name and arity are compatible if and only if they satisfy all the following rules:
-
The declared types of the arguments (defaulting to
item()*) are pairwise identical. -
The declared return types (defaulting to
item()*) are identical. -
The effective value of the
new-each-timeattribute on the overriding function is the same as its value on the overridden function. -
If the overridden function specifies
streamable="yes"then the overriding function also
-