absolute URI reference then it is used as is. If it is a
relative URI reference, then it is resolved against the base URI of
$base-node
if supplied, or against the base URI of the
node that contained it otherwise.
Each of these absolute URI references is then processed as
follows. Any fragment identifier that is present in the URI
reference is removed, and the resulting absolute URI is cast to a
string and then passed to the doc
FO30
function defined in [Functions and
Operators]. This returns a document node. If an error occurs
during evaluation of the doc
FO30
function, the processor may either signal
this error in the normal way, or may
recover by ignoring the failure, in which case the failing URI will
not contribute any nodes to the result of the document
function.
If the URI reference contained no fragment identifier, then this
document node is included in the sequence of nodes returned by the
document
function.
If the URI reference contained a fragment identifier, then the fragment identifier is interpreted according to the rules for the media type of the resource representation identified by the URI, and is used to select zero or more nodes that are descendant-or-self nodes of the returned document node. As described in 2.3 Initiating a Transformation, the media type is available as part of the evaluation context for a transformation.
The sequence of nodes returned by the function is in document
order, with no duplicates. This order has no necessary relationship
to the order in which URIs were supplied in the
$uri-sequence
argument.
[ERR XTDE1160] When a URI reference contains a fragment identifier, it is a dynamic error if the media type is not one that is recognized by the processor, or if the fragment identifier does not conform to the rules for fragment identifiers for that media type, or if the fragment identifier selects something other than a sequence of nodes (for example, if it selects a range of characters within a text node).
A processor may provide an option which, if selected, causes the processor instead of signaling this error, to ignore the fragment identifier and return the document node.
The set of media types recognized by a processor is implementation-defined.
[ERR XTDE1162] When a URI reference is a relative reference, it is a dynamic error if no base URI is available to resolve the relative reference. This can arise for example when the URI is contained in a node that has no base URI (for example a parentless text node), or when the second argument to the function is a node that has no base URI, or when the base URI from the static context is undefined.
One effect of these rules is that unless XML entities or
xml:base
are used, and provided that the base URI of
the stylesheet module is known, document("")
refers to
the document node of the containing stylesheet module (the
definitive rules are in [RFC3986]). The XML
resource containing the stylesheet module is processed exactly as
if it were any other XML document, for example there is no special
recognition of xsl:text
elements, and no special treatment of comments and processing
instructions.
The XPath rules for function calling ensure that it is a type error if the supplied value of the second argument is anything other than a single node. If XPath 1.0 compatibility mode is enabled, then a sequence of nodes may be supplied, and the first node in the sequence will be used.
Keys provide a way to work with documents that contain an implicit cross-reference structure. They make it easier to locate the nodes within a document that have a given value for a given attribute or child element, and they provide a hint to the implementation that certain access paths in the document need to be efficient.
xsl:key
Declaration
<xsl:key
name = eqname
match = pattern
use? = expression
composite? = "yes" | "no"
collation? = uri >

</xsl:key>
The xsl:key
declaration is used to declare keys. The name
attribute specifies the name of the key. The value of the
name
attribute is an EQName, which is expanded as
described in 5.1 Qualified Names. The
match
attribute is a Pattern; an xsl:key
element applies to all
nodes that match the pattern specified in the match
attribute.
[Definition: A key is defined as a
set of xsl:key
declarations
in the same package that share the same
name.]
The key name is scoped to the containing package, and is available
for use in calls to the key
function within that package.
The value of the key may be specified either using the
use
attribute or by means of the contained sequence constructor.
[ERR XTSE1205] It is a static error if an
xsl:key
declaration has a
use
attribute and has non-empty content, or if it has
empty content and no use
attribute.
If the use
attribute is present, its value is an
expression specifying the values of the key.
The expression will be evaluated with a singleton focus based on the node that
matches the pattern. The result of evaluating the expression
is atomized.
Similarly, if a sequence constructor is present, it is used to determine the values of the key. The sequence constructor will be evaluated with the node that matches the pattern as the context node. The result of evaluating the sequence constructor is atomized.
[Definition: The expression in the use
attribute and the sequence constructor within an
xsl:key
declaration are
referred to collectively as the key specifier. The key
specifier determines the values that may be used to find a node
using this key.]
When evaluation of the key specifier results in a sequence
(after atomization) containing more than one atomic value, the
effect depends on the value of the composite
attribute:
When the attribute is absent or has the value no
,
each atomic value in the sequence acts as an individual key. For
example, if match="book" use="author" composite="no"
is specified, then a book
element may be located using
the value of any author
element.
When the attribute is present and has the value
yes
, the sequence of atomic values is treated as a
composite key that must be matched in its entirety. For example, if
match="book" use="author" composite="yes"
is
specified, then a book
element may be located using
the value of all its author
elements, supplied in the
correct order.
If there are several xsl:key
declarations in the
same package with the same key name, then they must
all have the same effective value for their composite
attribute. The effective value is the actual value of the attribute
if present, or "no" if the attribute is absent.
Note:
There is no requirement that all the values of a key should have the same type.
The presence of an xsl:key
declaration makes it easy
to find a node that matches the match
pattern if the
values of the key specifier (when applied to that node)
are known. It also provides a hint to the implementation that
access to the nodes by means of these values needs to be efficient
(many implementations are likely to construct an index or hash
table to achieve this).
Note:
An xsl:key
declaration
is not bound to a specific source document. The source document to
which it applies is determined only when the key
function is used to locate nodes
using the key. Keys can be used to locate nodes within any source
document (including temporary trees), but each use of the key
function searches one document
only.
The optional collation
attribute is used only when
deciding whether two strings are equal for the purposes of key
matching. Specifically, two key values $a
and
$b
are considered equal if the result of the function
call deep-equal($a, $b, $collation)
is
true. The effective collation for an xsl:key
declaration is the
collation specified in its collation
attribute if
present, resolved against the base URI of the xsl:key
element, or the default collation that is in scope for
the xsl:key
declaration
otherwise; the effective collation must be the same for all the
xsl:key
declarations making
up a key.
[ERR XTSE1210] It is a static error if the
xsl:key
declaration has a
collation
attribute whose value (after resolving
against the base URI) is not a URI recognized by the implementation
as referring to a collation.
[ERR XTSE1220] It is a static error if there
are several xsl:key
declarations in the same package with the same key name and
different effective collations. Two collations are the same if
their URIs are equal under the rules for comparing
xs:anyURI
values, or if the implementation can
determine that they are different URIs referring to the same
collation.
[ERR XTSE1222] It is a static error if there
are several xsl:key
declarations in the stylesheet with the same key name and
different effective values for the composite
attribute.
It is possible to have:
multiple xsl:key
declarations with the same name;
a node that matches the match
patterns of several
different xsl:key
declarations, whether these have the same key name or different key
names;
a node that returns more than one value from its key specifier (which can be treated either as separate individual key values, or as a single composite key value);
a key value that identifies more than one node (the key values for different nodes do not need to be unique).
An xsl:key
declaration
with higher import precedence does not override
another of lower import precedence; all the xsl:key
declarations in the
stylesheet are effective regardless of their import precedence.
Returns the nodes that match a supplied key value.
key ( |
$key-name |
as xs:string , |
$key-value |
as xs:anyAtomicType* ) as node()* |
key ( |
$key-name |
as xs:string , |
$key-value |
as xs:anyAtomicType* , |
|
$top |
as node() ) as node()* |
The two-argument form of this function is deterministicFO30, focus-dependentFO30, and context-dependentFO30.
The three-argument form of this function is deterministicFO30, focus-independentFO30, and context-dependentFO30.
The key
function does for
keys what the
element-with-id
FO30
function does for IDs.
The $key-name
argument specifies the name of the
key. The value of
the argument must be a string
containing an EQName. If it is a lexical QName, then it
is expanded as described in 5.1 Qualified
Names (no prefix means no namespace).
The $key-value
argument to the key
function is considered as a
sequence. The effect depends on the value of the
composite
attribute of the corresponding
xsl:key
declaration.
If composite
is no
or
absent, the set of requested key values is formed by
atomizing the supplied value of the argument, using the standard
function conversion rules. Each
of the resulting atomic values is considered as a requested key
value. The result of the function is a sequence of nodes, in
document order and with duplicates removed, comprising those nodes
in the selected subtree (see below) that are matched by an xsl:key
declaration whose name is
the same as the supplied key name, where the result of evaluating
the key specifier contains a value that is
equal to one of these requested key values, under the rules
appropriate to the XPath eq
operator for the two
values in question, using the collation
attributes of
the xsl:key
declaration
when comparing strings. No error is reported if two values are
encountered that are not comparable; they are regarded for the
purposes of this function as being not equal.
If the second argument is an empty sequence, the result of the function will be an empty sequence.
If composite
is yes
, the requested key
value is the sequence formed by atomizing the supplied value of the
argument, using the standard function
conversion rules. The result of the function is a sequence of
nodes, in document order and with duplicates removed, comprising
those nodes in the selected subtree (see below) that are matched by
an xsl:key
declaration
whose name is the same as the supplied key name, where the result
of evaluating the key specifier is deep-equal to the
requested key value, under the rules appropriate to the deep-equal
FO30
function applied to the two values in question, using the
collation
attributes of the xsl:key
declaration when comparing
strings. Note that the deep-equal
FO30
function reports no error if two values are encountered that are
not comparable; they are regarded for the purposes of this function
as being not equal.
If the second argument is an empty sequence, the result of the function will be the set of nodes having an empty sequence as the value of the key specifier.
Different rules apply when XSLT 1.0 compatible behavior is enabled.
A key (that is, a set of xsl:key
declarations sharing the
same key name) is processed in backwards compatible mode if (a) at
least one of the xsl:key elements in the definition of the key
enables backwards compatible behavior, and (b) the effective value
of the composite
attribute is no
.
When a key is processed in backwards compatible mode, then:
The result of evaluating the key specifier in any xsl:key
declaration having this key
name is converted after atomization to a sequence of strings, by
applying a cast to each item in the sequence.
When the first argument to the key
function specifies this key name,
then the value of the second argument is converted after
atomization to a sequence of strings, by applying a cast to each
item in the sequence. The values are then compared as strings.
The third argument is used to identify the selected subtree. If
the argument is present, the selected subtree is the set of nodes
that have $top as an ancestor-or-self node. If the
argument is omitted, the selected subtree is the document
containing the context node. This means that the third argument
effectively defaults to /
.
The result of the key
function can be described more specifically as follows. The result
is a sequence containing every node $N that satisfies
the following conditions:
$N/ancestor-or-self::node() intersect $top
is
non-empty. (If the third argument is omitted, $top
defaults to /
)
$N matches the pattern specified in the
match
attribute of an xsl:key
declaration whose
name
attribute matches the name specified in the
$key-name
argument.
When composite="no"
, and the key
specifier of that xsl:key
declaration is evaluated
with a singleton focus based on $N,
the atomized value of the resulting sequence
includes a value that compares equal to at least one item in the
atomized value of the sequence supplied as $key-value
,
under the rules of the eq
operator with the collation
selected as described above.
When composite="yes"
, and the
key specifier of that xsl:key
declaration is evaluated
with a singleton focus based on $N,
the atomized value of the resulting sequence
compares equal to the atomized value of the sequence supplied as
$key-value
, under the rules of the deep-equal
FO30
function with the collation selected as described above.
The sequence returned by the key
function will be in document
order, with duplicates (that is, nodes having the same identity)
removed.
[ERR XTDE1260] It is a dynamic error if the
value is not a valid QName, or if there is no namespace declaration
in scope for the prefix of the QName, or if the name obtained by
expanding the QName is not the same as the expanded name of any
xsl:key
declaration in the
containing package. If the processor is able to
detect the error statically (for example, when the argument is
supplied as a string literal), then the processor may optionally signal this as a static
error.
[ERR XTDE1270] It is a dynamic error to call the key
function with two arguments if
there is no context node, or if the root of the tree
containing the context node is not a document node; or to call the
function with three arguments if the root of the tree containing
the node supplied in the third argument is not a document node.
Untyped atomic values are converted to strings, not to the type
of the other operand. This means, for example, that if the
expression in the use
attribute returns a date,
supplying an untyped atomic value in the call to the key
function will return an empty
sequence.
Given a declaration
<xsl:key name="idkey" match="div" use="@id"/>
an expression key("idkey",@ref)
will return the
same nodes as id(@ref)
, assuming that the only ID
attribute declared in the XML source document is:
<!ATTLIST div id ID #IMPLIED>
and that the ref
attribute of the context node
contains no whitespace.
Suppose a document describing a function library uses a
prototype
element to define functions
<prototype name="sqrt" return-type="xs:double"> <arg type="xs:double"/> </prototype>
and a function
element to refer to function
names
<function>sqrt</function>
Then the stylesheet could generate hyperlinks between the references and definitions as follows:
<xsl:key name="func" match="prototype" use="@name"/> <xsl:template match="function">   <xsl:apply-templates/>   </xsl:template> <xsl:template match="prototype">
  Function:  ...
 </xsl:template>
When called with two arguments, the key
function always returns nodes that
are in the same document as the context node. To retrieve a node
from any other document, it is necessary either to change the
context node, or to supply a third argument.
For example, suppose a document contains bibliographic
references in the form
<bibref>XSLT</bibref>
, and there is a
separate XML document bib.xml
containing a
bibliographic database with entries in the form:
<entry name="XSLT">...</entry>
Then the stylesheet could use the following to transform the
bibref
elements:
<xsl:key name="bib" match="entry" use="@name"/> <xsl:template match="bibref"> <xsl:variable name="name" select="."/> <xsl:apply-templates select="document('bib.xml')/key('bib',$name)"/> </xsl:template>
Note:
This relies on the ability in XPath 2.0 to have a function call
on the right-hand side of the /
operator in a path
expression.
The following code would also work:
<xsl:key name="bib" match="entry" use="@name"/> <xsl:template match="bibref"> <xsl:apply-templates select="key('bib', ., document('bib.xml'))"/> </xsl:template>
This example uses a composite key consisting of first name and last name to locate employees in an employee file.
The key can be defined like this:
<xsl:key name="emp-name-key" match="employee" use="name/first, name/last" composite="yes"/>
A particular employee can then be located using the function call:
key('emp-name-key', ('Tim', 'Berners-Lee'), doc('employees.xml'))
Returns the item that is the context item for the evaluation of the containing XPath expression
current
() as
item()
This function is deterministicFO30, context-dependentFO30, and focus-dependentFO30.
The current
function,
used within an XPath expression, returns the item that was the
context item at the point where the
expression was invoked from the XSLT stylesheet. This is referred to
as the current item. For an outermost expression (an expression not
occurring within another expression), the current item is always
the same as the context item. Thus,
<xsl:value-of select="current()"/>
means the same as
<xsl:value-of select="."/>
However, within square brackets, or on the right-hand side of
the /
operator, the current item is generally
different from the context item.
If the current
function
is used within a pattern, its value is the item that
is being matched against the pattern.
[ERR XTDE1360] If the current
function is evaluated
within an expression that is evaluated when the context item is
absent, a dynamic error occurs.
When the current
is
called by means of a dynamic function call (for example,
current#0()
), it is evaluated as if the context item
is absent ([see ERR
XTDE1360]).
The instruction:
<xsl:apply-templates select="//glossary/entry[@name=current()/@ref]"/>
will process all entry
elements that have a
glossary
parent element and that have a
name
attribute with value equal to the value of the
current item's ref
attribute. This is different
from
<xsl:apply-templates select="//glossary/entry[@name=./@ref]"/>
which means the same as
<xsl:apply-templates select="//glossary/entry[@name=@ref]"/>
and so would process all entry
elements that have a
glossary
parent element and that have a
name
attribute and a ref
attribute with
the same value.
Returns the URI (system identifier) of an unparsed entity
unparsed-entity-uri
($entity-name
as
xs:string
) as
xs:anyURI
This function is deterministicFO30, focus-dependentFO30, and context-dependentFO30.
The unparsed-entity-uri
function returns the URI of the unparsed entity whose name is given
by the value of the $entity-name
argument, in the
document containing the context node. It returns the
zero-length xs:anyURI
if there is no such entity. This
function maps to the dm:unparsed-entity-system-id
accessor defined in [Data
Model].
[ERR XTDE1370] It is a dynamic error if the
unparsed-entity-uri
function is called when there is no context node, or when the
root of the tree containing the context node is not a document
node.
Returns the public identifier of an unparsed entity
unparsed-entity-public-id
($entity-name
as
xs:string
) as
xs:anyURI
This function is deterministicFO30, focus-dependentFO30, and context-dependentFO30.
The unparsed-entity-public-id
function returns the public identifier of the unparsed entity whose
name is given by the value of the $entity-name
argument, in the document containing the context node. It
returns the zero-length string if there is no such entity, or if
the entity has no public identifier. This function maps to the
dm:unparsed-entity-public-id
accessor defined in
[Data Model].
[ERR XTDE1380] It is a dynamic error if the
unparsed-entity-public-id
function is called when there is no context node, or when the
root of the tree containing the context node is not a document
node.
Returns the value of a system property
system-property
($property-name
as
xs:string
) as
xs:string
This function is deterministicFO30, focus-independentFO30, and context-dependentFO30.
The $property-name
argument must evaluate to a lexical QName. The lexical
QName is expanded as described in 5.1
Qualified Names.
The system-property
function
returns a string representing the value of the system property
identified by the name. If there is no such system property, the
zero-length string is returned.
Implementations must provide the following system properties, which are all in the XSLT namespace:
xsl:version
, a number giving the version of XSLT
implemented by the processor; for implementations conforming to
the version of XSLT specified by this document, this is the string
"3.0"
. The value will always be a string
in the lexical space of the decimal data type defined in XML Schema
(see [XML Schema Part 2]). This allows
the value to be converted to a number for the purpose of magnitude
comparisons.
xsl:vendor
, a string identifying the implementer of
the processor
xsl:vendor-url
, a string containing a URL
identifying the implementer of the processor; typically this is the
host page (home page) of the implementer's Web site.
xsl:product-name
, a string containing the name of
the implementation, as defined by the implementer. This
should normally remain constant from one
release of the product to the next. It should also be constant across platforms in cases
where the same source code is used to produce compatible products
for multiple execution platforms.
xsl:product-version
, a string identifying the
version of the implementation, as defined by the implementer. This
should normally vary from one release of
the product to the next, and at the discretion of the implementer
it may also vary across different
execution platforms.
xsl:is-schema-aware
, returns the string
"yes"
in the case of a processor that claims
conformance as a schema-aware XSLT
processor, or "no"
in the case of a basic XSLT processor.
xsl:supports-serialization
, returns the string
"yes"
in the case of a processor that offers the
serialization feature, or
"no"
otherwise.
xsl:supports-backwards-compatibility
, returns the
string "yes"
in the case of a processor that offers
the XSLT 1.0 compatibility
feature, or "no"
otherwise.
xsl:supports-namespace-axis
, returns the string
"yes"
in the case of a processor that offers the XPath
namespace axis even when not in backwards compatible mode, or
"no"
otherwise. Note that a processor that supports
backwards compatible mode must support the namespace axis when in
that mode, so this property is not relevant to that case.
xsl:supports-streaming
, returns the string
"yes"
in the case of a processor that offers the
streaming feature (see 26.5
Streaming Feature), or "no"
otherwise.
xsl:supports-dynamic-evaluation
, returns the string
"yes"
in the case of a processor that offers the
dynamic evaluation feature (see 26.6 Dynamic Evaluation
Feature), or "no"
otherwise.
Some of these properties relate to the conformance levels and features offered by the processor: these options are described in 26 Conformance.
The actual values returned for the above properties are implementation-defined.
The set of system properties that are supported, in addition to those listed above, is also implementation-defined. Implementations must not define additional system properties in the XSLT namespace.
[ERR XTDE1390] It is a dynamic error if the
value supplied as the $property-name
argument is not a
valid QName, or if there is no namespace declaration in scope for
the prefix of the QName. If the processor is able to detect the
error statically (for example, when the argument is supplied as a
string literal), then the processor may
optionally signal this as a static error.
An implementation must not return the value
3.0
as the value of the
xsl:version
system property unless it is conformant to
XSLT 3.0.
It is recognized that vendors who are enhancing XSLT 1.0
or 2.0 processors may wish to release interim
implementations before all the mandatory features of this
specification are implemented. Since such products are not
conformant to XSLT 3.0, this specification cannot define their
behavior. However, implementers of such products are encouraged to
return a value for the xsl:version
system property
that is intermediate between 1.0 and 3.0, and to provide the
element-available
and
function-available
functions to allow users to test which features have been fully
implemented.
XSLT 3.0 extends the type system and data model of XPath 3.0 with additional datatypes and associated functions and operators defined in this section.
A map is an additional kind of item.
[Definition: A map consists of a set of entries. Each entry comprises a key which is an arbitrary atomic value, and an arbitrary sequence called the associated value.]
[Definition: Within a map,
no two entries have the same key. Two atomic values
K1
and K2
are the same key for
this purpose if the relation deep-equal(K1, K2, $UCC)
holds, where $UCC
is the Unicode codepoint
collation.]
To put it another way, the keys are the same if either K1
eq K2
is true under the Unicode codepoint collation, or if
both K1
and K2
are NaN
. It
is not necessary that all the keys should be mutually comparable
(for example, they can include a mixture of integers and
strings).
The function call map:get($map, $key)
can be used
to retrieve the value associated with a given key.
A map can also be viewed as a function from keys to associated values. To achieve this, a map is also a function item. The properties of this function are as follows:
The name of the function is absent.
The arity of the function is 1 (one).
The parameter names comprise a sequence of one QName,
conventionally $key
, though the choice of name has no
observable consequences.
The signature is function($key as
xs:anyAtomicValue) as item()*
(with no annotations).
The implementation is the expression map:get($self,
$key)
The non-local-variable-bindings comprise a single
variable, $self
, whose value is the map itself.
Calling the function has the same effect as calling the
get
function: the expression $map($key)
returns the same result as get($map, $key)
. For
example, if $books-by-isbn
is a map whose keys are
ISBNs and whose associated values are book
elements,
then the expression $books-by-isbn("0470192747")
returns the book
element with the given ISBN. The fact
that a map is a function item allows it to be passed as an argument
to higher-order functions that expect a function item as one of
their arguments.
Like all other values, maps are immutable. For example, the map:remove
function creates a
new map by removing an entry from an existing map, but the existing
map is not changed by the operation.
Like sequences, maps have no identity. It is meaningful to compare the contents of two maps, but there is no way of asking whether they are "the same map": two maps with the same content are indistinguishable.
The syntax of ItemTypeXP30 as defined in XPath is extended as follows:
| [69] | ItemType |
::= | KindTest | ("item" "(" ")") | FunctionTest |
AtomicOrUnionType | ParenthesizedItemType |
| [201] | MapType |
::= | 'map' '(' ( '*' | (AtomicOrUnionTypeXP30
',' SequenceTypeXP30)
')' |
The following rules express the matching rules for a map item type and a map, and extend the set of rules given in Section <IP_ADDRESS> Matching an ItemType and an Item XP30:
The ItemType
map(K, V)
matches an item
M if (a) M is a map, and (b) every entry in
M has a key that matches K
and an
associated value that matches V
. For example,
map(xs:integer, element(employee))
matches a map if
all the keys in the map are integers, and all the associated values
are employee
elements. Note that a map (like a
sequence) carries no intrinsic type information separate from the
types of its entries, and the type of existing entries in a map
does not constrain the type of new entries that can be added to the
map.
Note:
In consequence, map(K, V)
matches an empty map,
whatever the types K and V might be.
The ItemType
map(*)
matches any map
regardless of its contents. It is equivalent to
map(xs:anyAtomicType, item()*)
.
A map also acts as a function. This means that maps match certain function item types. Specifically, the following rule extends the list of rules in Section <IP_ADDRESS> Function Test XP30:
function(*)
matches any map.
function(xs:anyAtomicType) as item()*
matches any
map.
Because of the rules for subtyping of function types according
to their signature, it follows that the item type function(A)
as item()*
, where A is an atomic type, also matches any map,
regardless of the type of the keys actually found in the map. For
example, a map whose keys are all strings can be supplied where the
required type is function(xs:integer) as item()*
; a
call on the map that treats it as a function with an integer
argument will always succeed, and will always return an empty
sequence.
The function signature of the map, treated as a function, is
always function(xs:anyAtomicType) as item()*
,
regardless of the actual types of the keys and values in the map.
This means that a function item type with a more specific return
type, such as function(xs:anyAtomicType) as
xs:integer
, does not match a map in the sense required to
satisfy the instance of
operator. However, the rules
for function coercion mean that any map can be supplied as a value
in a context where such a type is the required type, and a type
error will only occur if an actual call on the map (treated as a
function) returns a value that is not an instance of the required
return type.
Note:
So, given a map $M
whose keys are integers and
whose results are strings, such as map{0:"no",
1:"yes"}
, the following relations hold, among others:
$M instance of map(*)
$M instance of map(xs:integer, xs:string)
$M instance of map(xs:decimal,
xs:anyAtomicType)
not($M instance of map(xs:int, xs:string))
not($M instance of map(xs:integer, xs:token))
$M instance of function(*)
$M instance of function(xs:anyAtomicType) as
item()*
$M instance of function(xs:integer) as item()*
$M instance of function(xs:int) as item()*
$M instance of function(xs:string) as item()*
not($M instance of function(xs:integer) as
xs:string)
The last case might seem surprising; however, function coercion
ensures that $M
can be used successfully anywhere that
the required type is function(xs:integer) as
xs:string
.
The rules for judging whether one item type is a subtype of
another, given in Section
<IP_ADDRESS> The judgement subtype-itemtype(Ai, Bi)
XP30, are extended with some additional
rules. The judgement subtype-itemtype(Ai, Bi)
is true
if:
Ai
is map(*)
and Bi
is
map(K, V)
, for any K
and
V
.
Ai
is map(Ka, Va)
and Bi
is map(Kb, Vb)
, where subtype-itemtype(Kb,
Ka)
and subtype-itemtype(Vb, Va)
.
Ai
is function(*)
and Bi
is map(*)
, (or, because of the transitivity rules, any
other map type).
Ai
is function(xs:anyAtomicType) as
item()*
and Bi
is map(*)
, (or,
because of the transitivity rules, any other map type).
The functions defined in this section use a conventional
namespace prefix map
, which is assumed to be bound to
the namespace URI
http://www.w3.org/2005/xpath-functions/map
.
There is no operation to atomize a map or convert it to a string.
The number of entries in the map may be obtained as
count(map:keys($map))
.
Creates a new map: either an empty map, or a map that combines entries from a number of existing maps.
new
() as
map(*)
new
($maps
as
map(*)*
) as
map(*)
This function is deterministicFO30, context-independentFO30, and focus-independentFO30.
The function map:new
constructs and returns a new map.
The zero-argument form of the function returns an empty map. It is equivalent to calling the one-argument form of the function with an empty sequence as the value of the first argument.
The one-argument form of the function returns a map that is formed by combining
the contents of the maps supplied in the $input
argument.
The supplied maps are combined as follows:
There is one entry in the new map for each distinct key value present in the union of the input maps, where two keys are distinct if they are not the same key.
The associated value for each such key is taken from the last
map in the input sequence $input
that contains an
entry with this key.
There is no requirement that the supplied input maps should have
the same or compatible types. The type of a map (for example
map(xs:integer, xs:string)
) is descriptive of the
entries it currently contains, but is not a constraint on how the
map may be combined with other maps.
let $week
:= map{0:"Sonntag", 1:"Montag",
2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag", 5:"Freitag",
6:"Samstag"}
The expression map:new()
returns
map{}
. (Returns an empty map).
The expression map:new(())
returns
map{}
. (Returns an empty map).
The expression map:new((map:entry(0, "no"), map:entry(1,
"yes")))
returns map{0:"no", 1:"yes"}
.
(Returns a map with two entries).
The expression map:new(($week, {7:"Unbekannt"}))
returns map{0:"Sonntag", 1:"Montag", 2:"Dienstag",
3:"Mittwoch", 4:"Donnerstag", 5:"Freitag", 6:"Samstag",
7:"Unbekannt"}
. (The value of the existing map is
unchanged; a new map is created containing all the entries from
$week
, supplemented with a new entry.).
The expression map:new(($week, {6:"Sonnabend"}))
returns map{0:"Sonntag", 1:"Montag", 2:"Dienstag",
3:"Mittwoch", 4:"Donnerstag", 5:"Freitag", 6:"Sonnabend"}
.
(The value of the existing map is unchanged; a new map is
created containing all the entries from $week
, with
one entry replaced by a new entry. Both input maps contain an entry
with the key value 6
; the one used in the result is
the one that comes last in the input sequence.).
Returns a sequence containing all the key values present in a map
keys
($input
as
map(*)
) as
xs:anyAtomicType*
This function is deterministicFO30, context-independentFO30, and focus-independentFO30.
The function map:keys
takes any map as
its $input
argument and returns the keys that are
present in the map as a sequence of atomic values, in implementation-dependent order.
The number of items in the result will be the same as the number of entries in the map, and the result sequence will contain no duplicate values.
The expression map:keys(map{1:"yes", 2:"no"})
returns some permutation of (1,2)
. (The result is
in implementation-dependent
order.).
Tests whether a supplied map contains an entry for a given key
contains ( |
$map |
as map(*) , |
$key |
as xs:anyAtomicType ) as xs:boolean |
This function is deterministicFO30, context-independentFO30, and focus-independentFO30.
The function map:contains
returns true if
the map supplied
as $map
contains an entry with the same key
as the supplied value of $key
; otherwise it
returns false. The equality comparison uses the Unicode
codepoint collation; no error occurs if the map contains
keys that are not comparable with the supplied
$key
.
If the supplied key is xs:untypedAtomic
, it
is compared as an instance of xs:string
.
If the supplied key is the xs:float
or
xs:double
value NaN
, the function
returns true if there is an entry whose key is
NaN
, or false otherwise.
let $week
:= map{0:"Sonntag", 1:"Montag",
2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag", 5:"Freitag",
6:"Samstag"}
The expression map:contains($week, 2)
returns
true()
.
The expression map:contains($week, 9)
returns
false()
.
The expression map:contains(map{}, "xyz")
returns
false()
.
The expression map:contains(map{"xyz":23}, "xyz")
returns true()
.
The expression map:contains(map{"abc":23, "xyz":()},
"xyz")
returns true()
.
Returns the value associated with a supplied key in a given map.
get ( |
$map |
as map(*) , |
$key |
as xs:anyAtomicType ) as item()* |
This function is deterministicFO30, context-independentFO30, and focus-independentFO30.
The function map:get
attempts to find an entry within the map supplied as $map
that has
the same key as the supplied value of
$key
. If there is such an entry, it returns the
associated value; otherwise it returns an empty sequence. The
comparison uses the Unicode codepoint collation; no
error occurs if the map contains keys that are not comparable with
the supplied $key
.
If the supplied key is xs:untypedAtomic
, it is
compared as an instance of xs:string
. If
the supplied key is the xs:float
or
xs:double
value NaN
, the function returns
the value in the entry whose key is NaN
, if
there is such an entry, or the empty sequence otherwise.
Where values of different numeric types are numerically very close to each other, it can happen that the map contains two entries whose keys both match the supplied key, but which are not equal to each other. In this situation the entry that is returned is implementation-dependent.
A return value of ()
from map:get
could indicate that the
key is present in the map with an associated value of
()
, or it could indicate that the key is not present
in the map. The two cases can be distinguished by calling map:contains
.
Invoking the map as a function item has the same effect as calling
get
: that is, when $map
is a map, the
expression $map($K)
is equivalent to
map:get($map, $K)
. Similarly, the expression
map:get(map:get(map:get($map, 'employee'), 'name'),
'first')
can be written as
$map('employee')('name')('first')
.
let $week
:= map{0:"Sonntag", 1:"Montag",
2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag", 5:"Freitag",
6:"Samstag"}
The expression map:get($week, 4)
returns
"Donnerstag"
.
The expression map:get($week, 9)
returns
()
. (When the key is not present, the function
returns an empty sequence.).
The expression map:get(map:entry(7,()), 7)
returns
()
. (An empty sequence as the result can also
signify that the key is present and the associated value is an
empty sequence.).
Creates a map that contains a single entry (a key-value pair).
entry ( |
$key |
as xs:anyAtomicType , |
$value |
as item()* ) as map(*) |
This function is deterministicFO30, context-independentFO30, and focus-independentFO30.
The function map:entry
returns a new
map which
contains a single entry. The key of the entry in the new map is
$key
, and its associated value is
$value
.
The function map:entry
is intended primarily for
use in conjunction with the function map:new
. For
example, a map containing seven entries may be constructed like
this:
map:new(( map:entry("Su", "Sunday"), map:entry("Mo", "Monday"), map:entry("Tu", "Tuesday"), map:entry("We", "Wednesday"), map:entry("Th", "Thursday"), map:entry("Fr", "Friday"), map:entry("Sa", "Saturday") ))
Unlike the map expression ({...}
), this technique
can be used to construct a map with a variable number of entries,
for example:
map:new(for $b in //book return map:entry($b/isbn, $b))
The expression map:entry("M", "Monday")
returns
{"M":"Monday"}
.
Constructs a new map by removing an entry from an existing map
remove ( |
$map |
as map(*) , |
$key |
as xs:anyAtomicType ) as map(*) |
This function is deterministicFO30, context-independentFO30, and focus-independentFO30.
The function map:remove
returns a new
map. The entries
in the new map correspond to the entries of $map
,
excluding any entry whose key is the same key as
$key
.
No failure occurs if the input map contains no entry with the supplied key; the input map is returned unchanged
let $week
:= map{0:"Sonntag", 1:"Montag",
2:"Dienstag", 3:"Mittwoch", 4:"Donnerstag", 5:"Freitag",
6:"Samstag"}
The expression map:remove($week, 4)
returns
map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch",
5:"Freitag", 6:"Samstag"}
.
The expression map:remove($week, 23)
returns
map{0:"Sonntag", 1:"Montag", 2:"Dienstag", 3:"Mittwoch",
4:"Donnerstag", 5:"Freitag", 6:"Samstag"}
.
Applies a supplied function to every entry in a map, returning the concatenation of the results.
for-each-entry ( |
$input |
as map(*) , |
$action |
as function($key as
xs:anyAtomicType, $value as item()*) ) as item()* |
This function is deterministicFO30, context-independentFO30, and focus-independentFO30.
The function map:for-each-entry
takes any map as
its $input
argument and applies the supplied function
to each entry in the map, in implementation-dependent order; the result is the sequence
obtained by concatenating the results of these function calls.
The function supplied as $action
takes two
arguments. It is called supplying the key of the map entry as the
first argument, and the associated value as the second
argument.
The expression map:for-each-entry(map{1:"yes", 2:"no"},
function($k, $v){$k})
returns some permutation of
(1,2)
. (This function call is equivalent to
calling map:keys
. The result is in
implementation-dependent order.).
The expression
distinct-values(map:for-each-entry(map{1:"yes", 2:"no"},
function($k, $v){$v})
returns some permutation of
("yes", "no")
. (This function call returns the
distinct values present in the map, in implementation-dependent
order.).
The expression map:new(map:for-each-entry(map{"a":1,
"b":2}, function($k, $v){map:entry($k, $v+1)})
returns
map{"a":2, "b":3}
. (This function call returns a
map with the same keys as the input map, with the value of each
entry increased by one.).
This example converts the entries in a map to attributes on a newly constructed element node.
<xsl:variable name="dimensions" select="map{'height': 3, 'width': 4, 'depth': 5}"/> <xsl:function name="f:make-attribute" as="attribute()"> <xsl:param name="key" as="xs:string"/> <xsl:param name="value" as="xs:anyAtomicType"/> <xsl:attribute name="{$key}" select="string($value)"/> </xsl:function> <xsl:template name="convert"> <box> <xsl:sequence select="map:for-each-entry( $dimensions, f:make-attribute#2)"/> </box> </xsl:template>
The result is the element <box height="3" width="4"
depth="5"/>
.
Given a key value and a collation, generates an internal value with the property that the internal value is the same for any two keys that compare equal under the given collation.
collation-key
($key
as
xs:string
) as
xs:anyAtomicType
collation-key ( |
$key |
as xs:string , |
$collation |
as xs:string ) as xs:anyAtomicType |
This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on collations.
Calling the one-argument version of this function is equivalent to calling the two-argument version supplying the default collation as the second argument.
The function returns an implementation-defined value with
the property that collation-key($K1, $C) eq
collation-key($K2, $C)
if and only if compare($K1,
$K2, $C) = 0
.
If the collation URI is a relative reference, it is resolved against the static base URI.
An implementation is free to generate a collation key in any convenient way provided that it always generates the same collation key for two strings that are equal under the collation, and different collation keys for strings that are not equal. This holds only within a single execution scopeFO30; an implementation is under no obligation to generate the same collation keys during a subsequent unrelated query or transformation.
It is possible to define collations that do not have the ability to generate collation keys. Supplying such a collation will cause the function to fail. The ability to generate collation keys is an implementation-defined property of the collation.
An error is raised [ERR FOCH0004] FO30 if the specified collation does not support the generation of collation keys.
The function is provided primarily for use with maps. If a map
is required where codepoint equality is inappropriate for comparing
keys, then a common technique is to normalize the key value so that
equality matching becomes feasible. There are many ways keys can be
normalized, for example by use of functions such as upper-case
FO30,
lower-case
FO30,
normalize-space
FO30, or
normalize-unicode
, but this function provides a way of
normalizing them according to the rules of a specified collation.
For example, if the collation ignores accents, then the function
will generate the same collation key for two input strings that
differ only in their use of accents.
The result of the function can be of any atomic type.
For collations based on the Unicode Collation Algorithm, an
algorithm for computing collation keys is provided in [UNICODE TR10]. This algorithm generates binary
collation keys, which might be materialized as a value of type
xs:hexBinary
or xs:base64Binary
.
Implementations are not required to use
this algorithm.
This specification does not mandate that collation keys should retain ordering. This is partly because the primary use case is for maps, where only equality comparisons are required, and partly to allow the use of binary data types (which are currently unordered types) for the result. The specification may be revised in a future release to specify that ordering is preserved.
let $C
:=
"http://www.w3.org/2005/xpath-functions/collations/UCA?strength=primary"
The expression map:new((map{collation-key("A", $C):1},
map{collation-key("a", $C):2}))(collation-key("A", $C))
returns 2
. (Given that the keys of the two entries
are equal under the rules of the chosen collation, only one of the
entries can appear in the result; the one that is chosen is the one
from the last map in the input sequence. ).
The expression let $M : map{collation-key("A", $C):1,
collation-key("B", $C):2} return $M(collation-key("a", $C))
returns 1
. (The strings "A" and "a" have the same
collation key under this collation.).
As the above examples illustrate, it is important that when the
collation-key
function is used to add entries to a
map, then it must also be used when retrieving entries from the
map. This process can be made less error-prone by encapsulating the
map within a function: function($k) {$M(collation-key($k,
$collation)}
.
This function assesses whether two sequences are deep-equal to
each other. The function as described here extends the definition
of the XPath 3.0 deep-equal
FO30
to explain how it should handle maps; it is intended to replace the
existing deep-equal
FO30
function at some stage in the future.
deep-equal ( |
$parameter1 |
as item()* , |
$parameter2 |
as item()* ) as xs:boolean |
deep-equal ( |
$parameter1 |
as item()* , |
$parameter2 |
as item()* , |
|
$collation |
as xs:string ) as xs:boolean |
This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on collations.
The function delivers the same result as deep-equal
FO30
except when (at some level of recursion) it is necessary to compare
two function items. In the case of deep-equal
FO30,
comparing two function items raises a dynamic error. In the case of
this function, two function items that are both maps are compared
as follows.
If two items $i1
and $i2
to be
compared are both maps, the result is true
if and only if
all the following conditions apply:
Both maps have the same number of entries.
For every entry in the first map, there is an entry in the second map that:
has the same key (note that the collation is not used when comparing keys), and
has the same associated value (compared using the
fn:deep-equal
function, under the collation supplied
in the original call to fn:deep-equal
).
An error is raised [ERR FOTY0015] FO30 if either input sequence contains a function item that is not a map.
The expression fn:deep-equal(map{}, map{})
returns
true()
.
The expression fn:deep-equal(map{"a":1, "b":2}, map{"b":2,
"a":1.0})
returns true()
.
The expression fn:deep-equal(map{"a":xs:double('NaN')},
map{"a":xs:float('NaN')})
returns true()
.
let $at
:=
<attendees> <name last='Parker' first='Peter'/> <name last='Barker' first='Bob'/> <name first='Peter' last='Parker'/> </attendees>
The expression fn:deep-equal($at, $at/*)
returns
false()
.
The expression fn:deep-equal($at/name[1],
$at/name[2])
returns false()
.
The expression fn:deep-equal($at/name[1],
$at/name[3])
returns true()
.
The expression fn:deep-equal($at/name[1], 'Peter
Parker')
returns false()
.
Two instructions are added to XSLT to facilitate the construction of maps.

<xsl:map>

</xsl:map>
The instruction xsl:map
constructs and returns a new map.
The contained sequence constructor must evaluate to a sequence of maps: call this
$maps
.
The result of the instruction is then given by the XPath expression:
let $keys := Smaps!map:keys(.) return if (count($keys) = count(distinct-values($keys))) then map:new($maps) else error()
Note:
Informally: if there are duplicate keys among the sequence of maps, a dynamic error occurs. Otherwise, the resulting map contains the union of the map entries from the supplied sequence of maps.
[ERR XTDE3365] A dynamic error occurs if the set of keys in the maps resulting from evaluating the sequence constructor contains duplicates.
There is no requirement that the supplied input maps should have
the same or compatible types. The type of a map (for example
map(xs:integer, xs:string)
) is descriptive of the
entries it currently contains, but is not a constraint on how the
map may be combined with other maps.
[ERR XTTE3375] A type error occurs if the result
of evaluating the sequence constructor is not an instance of the
required type map(*)*
.
Note:
In practice, the effect of this rule is that the sequence
constructor contained in the xsl:map
instruction is severely
constrained: it doesn't make sense, for example, for it to contain
instructions such as xsl:element
that create new
nodes. As with other type errors, processors are free to signal the
error statically if they are able to determine that the sequence
constructor would always fail when evaluated.

<xsl:map-entry
key = expression
select? = expression >

</xsl:map-entry>
The instruction xsl:map-entry
constructs and
returns a singleton map: that is, a map which contains one key and
one value. Such a map is primarily used as a building block when
constructing maps using the xsl:map
instruction.
The select
attribute and the contained sequence
constructor are mutually exclusive: if a select
attribute is present, then the content must be empty except optionally for xsl:fallback
instructions.
[ERR XTSE3280] It is a static error if the
select
attribute of the xsl:map-entry
element is
present unless the element has has no children other than xsl:fallback
elements.
The key of the entry in the new map is the value obtained by
evaluating the expression in the key
attribute,
converted to the required type xs:anyAtomicType
by
applying the function conversion rules.
If the supplied key (after conversion) is of type
xs:untypedAtomic
, it is cast to
xs:string
.
The associated value is the value obtained by evaluating the
expression in the select
attribute, or the contained
sequence constructor, with no conversion. If there is no
select
attribute and the sequence constructor is
empty, the associated value is the empty sequence.
The following example binds a variable to a map whose content is statically known:
<xsl:variable name="week" as="map(xs:string, xs:string)"> <xsl:map> <xsl:map-entry key="'Mo'" select="'Monday'"/> <xsl:map-entry key="'Tu'" select="'Tuesday'"/> <xsl:map-entry key="'We'" select="'Wednesday'"/> <xsl:map-entry key="'Th'" select="'Thursday'"/> <xsl:map-entry key="'Fr'" select="'Friday'"/> <xsl:map-entry key="'Sa'" select="'Saturday'"/> <xsl:map-entry key="'Su'" select="'Sunday'"/> </xsl:map> </xsl:variable>
The following example binds a variable to a map acting as an index into a source document:
<xsl:variable name="index" as="map(xs:string, element(employee))"> <xsl:map> <xsl:for-each select="//employee"> <xsl:map-entry key="@empNr" select="."/> </xsl:for-each> </xsl:map> </xsl:variable>
A new kind of expression is added to the syntax of XPath.
The syntax of PrimaryExprXP30
is extended to permit MapExpr
as an additional
alternative.
| [52] | PrimaryExpr |
::= | Literal | VarRef | ParenthesizedExpr | ContextItemExpr |
FunctionCall | FunctionItemExpr |
| [202] | MapExpr |
::= | "map{" (KeyExpr ":" ValueExpr ("," KeyExpr ":" ValueExpr
)*)? "}" |
| [203] | KeyExpr |
::= | ExprSingleXP30 |
| [204] | ValueExpr |
::= | ExprSingleXP30 |
Note:
In some circumstances, it is necessary to include whitespace
before or after the colon to ensure that this grammar is correctly
parsed; this arises for example when the KeyExpr
ends
with a name and the ValueExpr
starts with a name.
The value of the expression is a map whose entries correspond to
the key-value pairs obtained by evaluating the successive
KeyExpr
and ValueExpr
expressions.
Each KeyExpr
expression is evaluated and atomized;
a dynamic error occurs if the result is not a single atomic value.
If the key value is of type xs:untypedAtomic
it is
converted to xs:string
. The associated value is the
result of evaluating the corresponding ValueExpr
. If
two or more entries have the same key then a
dynamic error occurs [see ERR XTDE3365].
For example, the following expression constructs a map with seven entries:
map { "Su" : "Sunday", "Mo" : "Monday", "Tu" : "Tuesday", "We" : "Wednesday", "Th" : "Thursday", "Fr" : "Friday", "Sa" : "Saturday" }
Note:
Unlike the map:new
function, the number of entries in a map that is constructed using
a map expression is known statically.
Maps have many uses, but their introduction to XSLT 3.0 was strongly motivated by streaming use cases. In essence, when a source document is processed in streaming mode, data that is encountered in the course of processing may need to be retained in variables for subsequent use, because the nodes cannot be revisited. This creates a need for a flexible data structure to accommodate such temporary data, and maps were designed to fulfil this need.
The xsl:map
instruction,
and the XPath MapExpr
construct, are exceptions to the
general rule that during streaming, only one downward selection
(one consuming subexpression) is permitted. They share this
characteristic with xsl:fork
. As with xsl:fork
, a streaming processor is
expected to be able to construct the map during a single pass of
the streamed input document, which may require multiple expressions
to be evaluated in parallel.
In the case of the xsl:map
instruction, this applies
only in the case where the instruction consists exclusively of
xsl:map-entry
(and
xsl:fallback
)
children, and not in more complex cases where the map entries are
constructed dynamically (for example using a control flow
implemented using xsl:choose
, xsl:for-each
, or xsl:call-template
).
For example, the following XPath expression is streamable, despite making two downward selections:
let $m := map{'price':xs:decimal(price), 'discount':xs:decimal(discount)} return ($m('price') - $m('discount'))
Analysis:
Because the return
clause is motionless, the
sweep of the
let
expression is the sweep of the map expression (the
expression in curly braces).
The sweep of a map expression is the maximum sweep of its key/value pairs.
For both key/value pairs, the key is motionless and the value is consuming.
The expression carefully atomizes both values, because retaining references to streamed nodes in a variable is not permitted.
Therefore the map expression, and hence the expression as a whole, is grounded and consuming.
See also: <IP_ADDRESS> Streamability of map expressions, <IP_ADDRESS> Streamability of xsl:map, <IP_ADDRESS> Streamability of xsl:map-entry
This section gives some examples of where maps can be useful.
This example uses maps in conjunction with the xsl:iterate
instruction to find
the highest-earning employee in each department, in a single
streaming pass of an input document containing employee
records.
<xsl:stream href="employees.xml"> <xsl:iterate select="*/employee"> <xsl:param name="highest-earners" as="map(xs:string, element(employee))" select="map:new()"/> <xsl:variable name="this" select="copy-of(.)" as="element(employee)"/> <xsl:next-iteration> <xsl:with-param name="highest-earners" select="let $existing := $highest-earners($this/department) return if ($existing/salary gt $this/salary) then $highest-earners else map:new($highest-earners, map:entry($this/department, $this))"/> </xsl:next-iteration> <xsl:on-completion> <xsl:for-each select="map:keys($highest-earners)"> <department name="{.}"> <xsl:copy-of select="$highest-earners(.)"/> </department> </xsl:for-each> </xsl:on-completion> </xsl:iterate> </xsl:stream>
A complex number might be represented as a map with two entries,
the keys being the xs:boolean
value true
for the real part, and the xs:boolean
value
false
for the imaginary part. A library for
manipulation of complex numbers might include functions such as the
following:
<xsl:variable name="REAL" static="yes" as="xs:int" select="0"/> <xsl:variable name="IMAG" static="yes" as="xs:int" select="1"/> <xsl:function name="i:complex" as="map(xs:int, xs:double)"> <xsl:param name="real" as="xs:double"/> <xsl:param name="imaginary" as="xs:double"/> <xsl:sequence select="map{ $REAL : $real, $IMAG : $imaginary }"/> </xsl:function> <xsl:function name="i:real" as="xs:double"> <xsl:param name="complex" as="map(xs:int, xs:double)"/> <xsl:sequence select="$complex($REAL)"/> </xsl:function> <xsl:function name="i:imaginary" as="xs:double"> <xsl:param name="complex" as="map(xs:int, xs:double)"/> <xsl:sequence select="$complex($IMAG)"/> </xsl:function> <xsl:function name="i:add" as="map(xs:int, xs:double)"> <xsl:param name="arg1" as="map(xs:int, xs:double)"/> <xsl:param name="arg2" as="map(xs:int, xs:double)"/> <xsl:sequence select="i:complex(i:real($arg1)+i:real($arg2), i:imaginary($arg1)+i:imaginary($arg2)"/> </xsl:function> <xsl:function name="i:multiply" as="map(xs:boolean, xs:double)"> <xsl:param name="arg1" as="map(xs:boolean, xs:double)"/> <xsl:param name="arg2" as="map(xs:boolean, xs:double)"/> <xsl:sequence select="i:complex( i:real($arg1)*i:real($arg2) - i:imaginary($arg1)*i:imaginary($arg2), i:real($arg1)*i:imaginary($arg2) + i:imaginary($arg1)*i:real($arg2))"/> </xsl:function>
Given a set of book
elements, it is possible to
construct an index in the form of a map allowing the books to be
retrieved by ISBN number.
Assume the book elements have the form:
<book> <isbn>0470192747</isbn> <author>Michael H. Kay</author> <publisher>Wiley</publisher> <title>XSLT 2.0 and XPath 2.0 Programmer's Reference</title> </book>
An index may be constructed as follows:
<xsl:variable name="isbn-index" as="map(xs:string, element(book))" select="map:new(for $b in //book return map{$b/isbn : $b})"/>
This index may then be used to retrieve the book for a given
ISBN using either of the expressions map:get($isbn-index,
"0470192747")
or $isbn-index("0470192747")
.
In this simple form, this replicates the functionality available
using xsl:key
and the
key
function. However, it also
provides capabilities not directly available using the key
function: for example, the index
can include book
elements in multiple source
documents. It also allows processing of all the books using a
construct such as <xsl:for-each
select="map:keys($isbn-index)">
As in JavaScript, a map whose keys are strings and whose associated values are function items can be used in a similar way to a class in object-oriented programming languages.
Suppose an application needs to handle customer order information that may arrive in three different formats, with different hierarchic arrangements:
Flat structure:
<customer id="c123">...</customer> <product id="p789">...</product> <order customer="c123" product="p789">...</order>
Orders within customer elements:
<customer id="c123"> <order product="p789">...</order> </customer> <product id="p789">...</product>
Orders within product elements:
<customer id="c123">...</customer> <product id="p789"> <order customer="c123">...</order> </product>
An application can isolate itself from these differences by
defining a set of functions to navigate the relationships between
customers, orders, and products: orders-for-customer
,
orders-for-product
, customer-for-order
,
product-for-order
. These functions can be implemented
in different ways for the three different input formats. For
example, with the first format the implementation might be:
<xsl:variable name="flat-input-functions" as="map(xs:string, function(*))*" select="map{ 'orders-for-customer' : function($c as element(customer)) as element(order)* {$c/../order[@customer=$c/@id]}, 'orders-for-product' : function($p as element(product)) as element(order)* {$p/../order[@product=$p/@id]}, 'customer-for-order' : function($o as element(order)) as element(customer) {$o/../customer[@id=$o/@customer]}, 'product-for-order' : function($o as element(order)) as element(product) {$o/../product[@id=$o/@product]} } "/>
Having established which input format is in use, the application
can bind the appropriate implementation of these functions to a
variable such as $input-navigator
, and can then
process the input using XPath expressions such as the following,
which selects all products for which there is no order:
//product[empty($input-navigator("orders-for-product")(.))]
JSON is a popular format for exchange of structured data on the web: it is specified in [RFC 4627] and in [ECMA-404]. This section describes facilities allowing JSON data to be processed using XSLT.
This specification defines a mapping from JSON data to XML
(specifically, to XDM instances). A function json-to-xml
is provided to
take a JSON string as input and convert it to the XML
representation. Two stylesheet modules are provided to perform the
reverse transformation: one produces JSON in compact linear form,
the other in indented form suitable for display, editing, or
printing.
The XML representation is designed to be capable of representing any valid JSON text other than one that uses characters which are not valid in XML. The transformation is lossless: that is, distinct JSON texts convert to distinct XML representations. When converting JSON to XML, options are provided to reject unsupported characters, to replace them with a substitute character, or to leave them in backslash-escaped form.
The following example demonstrates the correspondence of a JSON text and the corresponding XML representation.
Consider the following JSON text:
{ "first name" : "John", "last name" : "Smith", "retired" : true, "address" : { "street address" : "21 2nd Street", "city" : "New York", "state" : "NY", "postal code" : 10021 }, "phone numbers" : [ { "home": "212 732-1234", "fax": "646 123-4567" } ], "date of birth" : null }
The XML representation of this text is as follows. Whitespace is
included in the XML representation for purposes of illustration,
and is ignored by the stylesheets that convert XML to JSON, but it
will not be present in the output of the json-to-xml
function.
<map xmlns="http://www.w3.org/2013/XSL/json"> <string key='first name'>John</string> <string key='last name'>Smith</string> <boolean key="retired">true</boolean> <map key='address'> <string key='street address'>21 2nd Street</string> <string key='city'>New York</string> <string key='state'>NY</string> <number key='postal code'>10021</number> </map> <array key='phone numbers'> <map> <string key="home">212 732-1234</string> <string key="fax">646 123-4567</string> </map> </array> <null key="date of birth"/> </map>
An XSD 1.0 schema for the XML representation is provided in
B.1 Schema for the XML Representation
of JSON. It is not necessary to import this schema (using
xsl:import-schema
) unless
the stylesheet makes explicit reference to the components defined
in the schema. If the stylesheet does import a schema for the
namespace http://www.w3.org/2013/XSL/json
, then:
The processor (if it is schema-aware) must recognize an xsl:import-schema
declaration for this namespace, whether or not the
schema-location
is supplied.
If a schema-location
is provided, then the schema
document at that location must be
equivalent to the schema document at B.1 Schema for the XML Representation of
JSON; the effect if it is not is implementation-defined
The rules governing the mapping from JSON to XML are as follows.
In these rules, the term "an element named N" is to be interpreted
as meaning "an element node whose local name is N and whose
namespace URI is http://www.w3.org/2013/XSL/json
"
The JSON value null
is represented by an element
named null
, with empty content.
The JSON values true
and false
are
represented by an element named boolean
, with content
conforming to the type xs:boolean
.
A JSON number is represented by an element named
number
, with content conforming to the type
xs:double
, with the additional restriction that the
value must not be positive or negative infinity, nor
NaN
.
A JSON string is represented by an element named
string
, with content conforming to the type
xs:string
.
A JSON array is represented by an element named
array
. The content is a sequence of child elements
representing the members of the array in order, each such element
being the representation of the array member obtained by applying
these rules recursively.
A JSON object is represented by an element named
map
. The content is a sequence of child elements each
of which represents one of the name/value pairs in the object. The
representation of the name/value pair N:V is obtained by
taking the element that represents the value V (by
applying these rules recursively) and adding an attribute with name
key
(in no namespace), whose value is N as
an instance of xs:string
.
The attribute escaped="true"
may be specified on a
string
element to indicate that the string value
contains backslash-escaped characters that are to be interpreted
according to the JSON rules. The attribute
escaped-key="true"
may be specified on any element
with a key
attribute to indicate that the key value
contains backslash-escaped characters that are to be interpreted
according to the JSON rules. Both attributes have the default value
false
.
Although the order of entries in a JSON object is generally
considered to have no significance, the function
json-to-xml
and the stylesheets that perform the
reverse transformation both retain order.
The XDM representation of a JSON value may either be untyped
(all elements annotated as xs:untyped
, attributes as
xs:untypedAtomic
), or it may be typed. If it is typed,
then it must have the type annotations
obtained by validating the untyped representation against the
schema given in B.1 Schema for the
XML Representation of JSON. If it is untyped, then it
must be an XDM instance such that
validation against this schema would succeed.
Parses a string supplied in the form of a JSON text, returning the results in the form of an XML document node.
json-to-xml
($json-text
as
xs:string
) as
document-node()
json-to-xml ( |
$json-text |
as xs:string , |
$options |
as map(*) ) as document-node() |
This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on static base uri.
The effect of the one-argument form of this function is the same
as calling the two-argument form with an empty map as the value of
the $options
argument.
The first argument is a JSON-text (see below) in the form of a string. The function parses this string to return an XDM node.
The $options
argument can be used to control the
way in which the parsing takes place. The value of the argument is
a map. The options defined in this specification have keys that are
strings. The effect of any map entries whose keys are not defined
in this specification is implementation-defined;
implementation-defined options should use
QNames as keys. Implementations must
ignore any entries in the map whose keys are not defined in this
specification, unless the key has a specific implementation-defined
meaning.
The entries that may appear in the $options
map are
as follows. The keys are xs:string
values:
| Key | Value | Meaning |
|---|---|---|
spec |
Determines the
specification of JSON that is to be used. The value must be a string; the effect of supplying any value
other than "RFC4627" ,
"ECMA-404" , or "liberal" is
implementation-defined. The
default is "RFC4627" . |
|
"RFC4627" |
The input must conform to [RFC 4627], with no deviations from the grammar permitted. | |
"ECMA-404" |
The input must conform to the
specification in "ECMA-404" . |
|
"liberal" |
Indicates any implementation-defined superset of RFC4627 (or equivalently, an implementation that recovers from some or all errors in the input). | |
validate |
If the
$options map contains an entry with the key
"validate" , then the value must be an xs:boolean . The default is
true for a schema-aware processor, false
for a non-schema-aware processor. If the value true is
supplied and the processor is not schema-aware, a dynamic error
results [see ERR
XTDE3245]. It is not necessary that the containing
stylesheet should import the relevant schema. |
|
true |
Indicates that the resulting XDM
instance must be typed; that is, the element and attribute nodes
must carry the type annotations that result from validation against
the schema given at B.1 Schema for
the XML Representation of JSON, or against an implementation-defined schema if
the spec option has the value
liberal . |
|
false |
Indicates that the the XDM instance must be untyped. | |
unescape |
If the
$options map contains an entry with the key
"unescape" , then the value must be an xs:boolean . The value
determines whether escape sequences (marked by a backslash) in the
input are expanded. The default is true . |
|
false |
In the result, any
string element whose string value contains a backslash
character must have the attribute value
escaped="true" , and any element that contains a
key attribute whose string value contains a backslash
character must have the attribute escaped-key="true" .
(The value of the escaped and key-escaped
attributes is immaterial when there is no backslash present, and it
is never necessary to include either attribute when the value is
false .) The escaped representation in this case
may be used for any character, whether or
not it was escaped in the original JSON input. |
|
true |
The attributes escaped
and escaped-key will never be present with the value
true . If the input contains escape sequences
representing characters or codepoints that are not valid characters
in the version of XML supported by the implementation, such
characters are replaced by the Unicode replacement character
(xFFFD), or as described in the next paragraph. |
|
fallback |
Provides a function which is called when an invalid character is encountered. | |
Function with signature
function(xs:string) as xs:string |
When an invalid character is encountered this function is called supplying the escaped form of the character as the argument. The function returns a string which is inserted into the result in place of the invalid character. The function also has the option of raising a dynamic error. |
The various structures that can occur in JSON are transformed recursively to XDM values according to the rules given in 21.2.1 XML Representation of JSON.
The function returns a document node, whose only child is the element node representing the outermost construct in the JSON text.
The function is not : that is, if the function is called twice with the same arguments, it is implementation-dependent whether the same node is returned on both occasions.
The base URI of the returned document node is taken from the static base URI of the function call.
[ERR XTDE3240] It is a dynamic error if the
value of $input
does not conform to the JSON grammar,
as selected using the explicit or implicit spec
option.
[ERR XTDE3245] It is a dynamic error if the
value of the validate
option is true
and
the processor is not schema-aware.
[ERR XTDE3250] It is a dynamic error if the
value of $input
contains an escaped representation of
a character (or codepoint) that is not a valid character in the
version of XML supported by the implementation, unless the
unescape
option is set to false.
[ERR XTDE3260] It is a dynamic error if the
value of $options
includes an entry whose key is
"spec" and whose value is not a single xs:string
, or
an entry whose key is "validate" or "unescape" and whose value is
not a single xs:boolean
.
To read a JSON file, this function can be used in conjunction
with the
unparsed-text
FO30
function.
ECMA-404 differs from RFC 4627 in two respects: it does not allow the input to depart from the JSON grammar, but it does allow the top-level construct in the input to be a string, boolean, number, or null, rather than requiring an object or array.
Many JSON implementations allow commas to be used after the last
item in an object or array, although the specification does not
permit it. The option spec="liberal"
is provided to
allow such deviations from the specification to be accepted. Some
JSON implementations also allow constructors such as new
Date("2000-12-13")
to appear as values: specifying
spec="liberal"
allows such extensions to be accepted,
but does not guarantee it. If such extensions are accepted, the
resulting value is implementation-defined, and will not necessarily
conform to the schema at B.1 Schema
for the XML Representation of JSON.
The expression json-to-xml('{"x": 1, "y":
[3,4,5]}')
returns <map
xmlns="http://www.w3.org/2013/XSL/json"> <number
key="x">1</number> <array key="y">
<number>3</number> <number>4</number>
<number>5</number> </array>
</map>
.
The expression json-to-xml('"abcd"', map{'spec':
'RFC4627'})
raises error FOJS0001
. (This is
an error because RFC4627 requires the outermost construct in JSON
to be an array or object, not a string.).
The expression json-to-xml('"abcd"', map{'spec':
'ECMA-404'})
returns <string
xmlns="http://www.w3.org/2013/XSL/json">abcd</string>
.
The expression json-to-xml('{"x": "\\", "y":
"\u0025"}')
returns one of the following: <map
xmlns="http://www.w3.org/2013/XSL/json"> <string
key="x">\</string> <string key="y">%</string>
</map>
or map{"x": "\","y": "%"}
.
The expression json-to-xml('{"x": "\\", "y": "\u0025"}',
map{'unescape': false()})
returns <map
xmlns="http://www.w3.org/2013/XSL/json"> <string
escaped="true" key="x">\\</string> <string
escaped="true" key="y">\u0025</string>
</map>
.
The following example illustrates use of the fallback function to handle characters that are invalid in XML.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:err="http://example.com/ns/errors" xmlns:f="http://example.com/ns/functions" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs err f" version="3.0"> <xsl:template match="someElement"> <xsl:variable name="jsonstr" select="unparsed-text('http://example.com/endpoint')"/> <xsl:variable name="options" select="map{'spec':'liberal', 'fallback':f:convert#1}"/> <xsl:variable name="json" select="json-to-xml($jsonstr, $options)"/>  </xsl:template> <xsl:function name="f:convert" as="xs:string"> <xsl:param name="char" as="xs:string"/> <xsl:variable name="c0chars" select="{ '\u0000':'[NUL]', '\u0001':'[SOH]', '\u0002':'[STX]', ... '\u001E':'[RS]', '\u001F':'[US]'}"/> <xsl:variable name="replacement" select="$c0chars($char)"/> <xsl:sequence select="if (exists($replacement)) then $replacement else error(xs:QName('err:invalid-char'), 'Error: '||$char||' is not a terminal control char.'))"/> </xsl:function> </xsl:stylesheet>
Two stylesheets are provided whose effect is to convert the XML
representation of JSON defined in 21.2.1 XML Representation of JSON
to a string conforming to the JSON grammar. The stylesheets are
listed in B XML Representation of
JSON. They are presented as separate packages which
may be incorporated into a user stylesheet using xsl:use-package
.
The first stylesheet, xml-to-json.xsl
, produces a
JSON string containing minimal whitespace. The second,
xml-to-json-indented.xsl
, produces a JSON string with
whitespace indentation designed for human legibility.
The stylesheets are designed to be configurable by setting parameter values or by overriding selected template rules or functions.
The stylesheets define the punctuation characters of JSON as
parameters which can be overridden. This is intended to allow the
stylesheets to be adapted to produce map literals suitable for use
in other languages (PHP, for example, uses "=>"
rather than ":"
to separate keys from values). Setting
the punctuation characters can also be used to alter the amount of
whitespace in the result.
The conversion can be effected either by calling the public
function j:xml-to-json
, which takes an XML node as its
argument and produces the JSON string as its output, or by applying
templates to the XML node in mode j:xml-to-json
: this
delivers a sequence of text nodes, which may be processed for
example using:
<xsl:variable name="json"> <xsl:apply-templates select="$json-as-xml"/> </xsl:variable>
or:
<xsl:result-document href="output.json" method="text"> <xsl:apply-templates select="$json-as-xml"/> </xsl:result-document>
The stylesheets do not validate that the input conforms to the schema defined at B.1 Schema for the XML Representation of JSON, and the effect of using them with input that does not conform to this schema is unpredictable.

<xsl:message
select? = expression
terminate? = { "yes" | "no" }
error-code? = { eqname } >

</xsl:message>
The xsl:message
instruction sends a message in an implementation-defined way. The
xsl:message
instruction
causes the creation of a new document, which is typically
serialized and output to an implementation-defined
destination. The result of the xsl:message
instruction is an
empty sequence.
The content of the message may be specified by using either or
both of the optional select
attribute and the
sequence constructor that forms the
content of the xsl:message
instruction.
If the xsl:message
instruction contains a sequence constructor,
then the sequence obtained by evaluating this sequence constructor
is used to construct the content of the new document node, as
described in 5.8.1
Constructing Complex Content.
If the xsl:message
instruction has a select
attribute, then the value of
the attribute must be an XPath
expression. The effect of the xsl:message
instruction is then
the same as if a single xsl:copy-of
instruction with
this select
attribute were added to the start of the
sequence constructor.
If the xsl:message
instruction has no content and no select
attribute,
then an empty message is produced.
The tree produced by the xsl:message
instruction is not
technically a final result tree. The tree has no URI
and processors are not required to make
the tree accessible to applications.
Note:
In many cases, the XML document produced using xsl:message
will consist of a
document node owning a single text node. However, it may contain a
more complex structure.
Note:
An implementation might implement xsl:message
by popping up an
alert box or by writing to a log file. Because the order of
execution of instructions is implementation-defined, the order in
which such messages appear is not predictable.
The terminate
attribute is interpreted as an
attribute value template.
If the effective value of the
terminate
attribute is yes
, then the
processor must
signal a dynamic error after sending the
message. This error may be caught in the same way as any
other dynamic error using xsl:catch
. The default
value is no
. Note that because the order of evaluation
of instructions is implementation-dependent, this
gives no guarantee that any particular instruction will or will not
be evaluated before processing terminates.
The optional error-code
attribute may be used to
indicate the error code associated with the message. This may be
used irrespective of the value of terminate
. The error
code is an EQName. If no error code is specified, or
if the value is not a valid EQName, the error code will have local
part XTMM9000
and namespace URI
http://www.w3.org/2005/xqt-errors
. User-defined error
codes should be in a namespace other than
http://www.w3.org/2005/xqt-errors
. When the value of
terminate
is yes
, the error code may be
matched in an xsl:catch
element to catch the error and cause processing to continue
normally.
[ERR XTMM9000] When a transformation is
terminated by use of xsl:message terminate="yes"
, the
effect is the same as when a dynamic error occurs during
the transformation. The default error code is
XTMM9000
; this may be overridden using the
error-code
attribute of the xsl:message
instruction.
One convenient way to do localization is to put the localized
information (message text, etc.) in an XML document, which becomes
an additional input file to the stylesheet. For example,
suppose messages for a language L
are
stored in an XML file resources/L.xml
in
the form:
<messages> <message name="problem">A problem was detected.</message> <message name="error">An error was detected.</message> </messages>
Then a stylesheet could use the following approach to localize messages:
<xsl:param name="lang" select="'en'"/> <xsl:variable name="messages" select="document(concat('resources/', $lang, '.xml'))/messages"/> <xsl:template name="localized-message"> <xsl:param name="name"/> <xsl:message select="string($messages/message[@name=$name])"/> </xsl:template> <xsl:template name="problem"> <xsl:call-template name="localized-message"> <xsl:with-param name="name">problem</xsl:with-param> </xsl:call-template> </xsl:template>
Any dynamic error that occurs while evaluating
the select
expression or the contained sequence constructor, and any
serialization error that occurs while
processing the result, does not cause the transformation to
fail; at worst, it means that no message is output, or that the
only message that is output is one that relates to the error that
occurred..
Note:
An example of such an error is the serialization error that
occurs when processing the instruction <xsl:message
select="@code"/>
(on the grounds that free-standing
attributes cannot be serialized). Making such errors recoverable
means that it is implementation-defined whether or not they are
signaled to the user and whether they cause termination of the
transformation. If the processor chooses to recover from the error,
the content of any resulting message is
implementation-dependent.
One possible recovery action is to include a description of the error in the generated message text.
The xsl:assert
instruction is used to assert that the value of a particular
expression is true; if the value of the expression is false, and
assertions are enabled, then a dynamic error occurs.

<xsl:assert
test = expression
select? = expression
error-code? = { eqname } >

</xsl:assert>
By default, assertions are enabled. Checking of assertions may be disabled in several ways:
As with any other instruction, assertions may be disabled by use
of the use-when
attribute: see 3.14 Conditional Element
Inclusion.
An implementation should provide an external mechanism to disable assertion checking for the stylesheet as a whole (either statically or dynamically). The detail of such mechanisms is implementation-defined.
If assertion checking is enabled, the instruction is evaluated as follows:
The expression in the test
attribute is evaluated.
If the effective boolean value of the result is true
,
the assertion succeeds, and no further action is taken. If the
effective boolean value is false, or if a dynamic error occurs
during evaluation of the expression, then the assertion fails.
If the assertion fails, then the effect of the instruction is
governed by the rules for evaluation of an xsl:message
instruction with
the same select
attribute, error-code
attribute, and contained sequence constructor,
and with the value terminate="yes"
. However, the
default error code if the error-code
attribute is
omitted is XTMM9001
rather than
XTMM9000
.
Note:
To the extent that the behavior of xsl:message
is implementation-defined, this rule
does not prevent an implementation treating xsl:assert
and xsl:message
differently.
[ERR XTMM9001] When a transformation is
terminated by use of xsl:assert
, the effect is the
same as when a dynamic error occurs during the
transformation. The default error code is XTMM9001
;
this may be overridden using the error-code
attribute
of the xsl:assert
instruction.
As with any other dynamic error, an error caused by an assertion
failing may be trapped using xsl:try
: see 8.3 Try/Catch.
The result of the xsl:assert
instruction is an
empty sequence.
The following example shows a stylesheet function that checks
that the value of its supplied argument is in range. The check is
performed only if the static parameter
$DEBUG
is set to true.
<xsl:param name="DEBUG" as="xs:boolean" select="false()" static="yes" required="no"/> <xsl:function name="f:days-elapsed" as="xs:integer"> <xsl:param name="date" as="xs:date"/> <xsl:assert use-when="$DEBUG" test="$date lt current-date()"/> <xsl:sequence select="(current-date() - $since) div xs:dayTimeDuration('PT1D')"/> </xsl:function>
Note:
Implementations should avoid optimizing xsl:assert
instructions away. As
a guideline, if the result of a sequence constructor is required by
the transformation, the implementation should ensure that all
xsl:assert
instructions
in that sequence constructor are evaluated. Conversely, if the
result of a sequence constructor is not required by the
transformation, its xsl:assert
instructions should
not be evaluated.
This recommendation is not intended to prevent optimizations such as lazy evaluation, where evaluation of a sequence constructor may finish early, as soon as enough information is available to evaluate the containing instruction.
An implementation may provide a user option allowing a processor to treat assertions as being true without explicit checking. This option must not be enabled by default. If such an option is in force, the effect of any assertion not being true is implementation-dependent.
Note:
For example, given the assertion <xsl:assert
test="count(//title)=1"/>
, a processor might generate
code for the expression <xsl:value-of
select="//title"/>
that stops searching for
title
elements after finding the first one. In the
event that the source document contains more than one
title
, execution of the stylesheet may fail in
arbitrary ways, or it may produce incorrect output.
XSLT allows two kinds of extension, extension instructions and extension functions.
[Definition: An extension instruction is an element within a sequence constructor that is in a namespace (not the XSLT namespace) designated as an extension namespace.]
[Definition: An extension function is a function
that is available for use within an XPath expression, other than a
core function defined in [Functions and Operators], an additional
function defined in this XSLT specification, a constructor function
named after an atomic type, or a stylesheet
function defined using an xsl:function
declaration.].
This specification does not define any mechanism for creating or binding implementations of extension instructions or extension functions, and it is not required that implementations support any such mechanism. Such mechanisms, if they exist, are implementation-defined. Therefore, an XSLT stylesheet that must be portable between XSLT implementations cannot rely on particular extensions being available. XSLT provides mechanisms that allow an XSLT stylesheet to determine whether the implementation makes particular extensions available, and to specify what happens if those extensions are not available. If an XSLT stylesheet is careful to make use of these mechanisms, it is possible for it to take advantage of extensions and still retain portability.
The set of functions that can be called from a FunctionCallXP30 within an XPath expression may include one or more extension functions. The expanded QName of an extension function always has a non-null namespace URI.
Determines whether a particular function is or is not available
for use. The function is particularly useful for calling within an
[xsl:]use-when
attribute (see 3.14 Conditional Element
Inclusion) to test whether a particular extension function is available.
function-available
($function-name
as
xs:string
) as
xs:boolean
function-available ( |
$function-name |
as xs:string , |
$arity |
as xs:integer ) as xs:boolean |
This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on namespaces, and known function signatures.
A function is said to be available within an XPath expression if it is present in the statically known function signaturesXP30 for that expression (see 5.4.1 Initializing the Static Context). Functions in the static context are uniquely identified by the name of the function (a QName) in combination with its arity.
The value of the $function-name
argument
must be a string containing a EQName. The lexical
QName is expanded into an expanded QName using the namespace
declarations in scope for the expression. If the value is an unprefixed
lexical QName, then the standard
function namespace is used in the expanded QName.
The two-argument version of the function-available
function returns true if and only if there is an available function
whose name matches the value of the $function-name
argument and whose arity matches the value of the $arity
argument.
The single-argument version of the function-available
function returns true if and only if there is at least one
available function (with some arity) whose name matches the value
of the $function-name
argument.
When the containing expression is evaluated with XPath 1.0 compatibility mode set to
true, the function-available
function returns false in respect of a function name and arity for
which no implementation is available (other than the fallback error
function that raises a dynamic error whenever it is called). This
means that it is possible (as in XSLT 1.0) to use logic such as the
following to test whether a function is available before calling
it:
 <xsl:choose> <xsl:when test="function-available('my:summary')"> <xsl:value-of select="my:summary()"/> </xsl:when> <xsl:otherwise> <xsl:text>Summary not available</xsl:text> </xsl:otherwise> </xsl:choose>
[ERR XTDE1400] It is a dynamic error if the argument does not evaluate to a string that is a valid EQName, or if the value is a lexical QName with a prefix for which no namespace declaration is present in the static context. If the processor is able to detect the error statically (for example, when the argument is supplied as a string literal), then the processor may optionally signal this as a static error.
The fact that a function with a given name is available gives no guarantee that any particular call on the function will be successful. For example, it is not possible to determine the types of the arguments expected.
The introduction of the
function-lookup
FO30 function
in XPath 3.0 reduces the need for function-available
,
since
function-lookup
FO30 not only
tests whether a function is available, but also returns a function
item that enables it to be dynamically called.
If a function is present in the static context but with no
useful functionality (for example, if the system has been
configured for security reasons so that
available-environment-variables
FO30
returns no information), then function-available
when
applied to that function should return false.
It is not necessary that there be a direct equivalence between
the results of function-available
anr
function-lookup
FO30 in all
cases. For example, there may be extension
functions whose side-effects are such that for security
reasons, dynamic calls to the function are disallowed;
function-lookup
FO30 might then
not provide access to the function. The main use-case for function-available
, by
contrast, is for use in [xsl:]use-when
conditions to
test whether static calls on the function are possible.
A stylesheet that is designed to use XSLT 2.0 facilities when running under an XSLT 2.0 or XSLT 3.0 processor, but to fall back to XSLT 1.0 capabilities when not, might be written using the code:
<out xsl:version="2.0"> <xsl:choose> <xsl:when test="function-available('matches')"> <xsl:value-of select="matches(/doc/title, '[a-z]*')"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="string-length( translate(/doc/title, 'abcdefghijklmnopqrstuvwxyz', '')) = 0"/> </xsl:otherwise> </xsl:choose> </out>
Here an XSLT 2.0 or XSLT 3.0 processor will always
take the xsl:when
branch,
while a 1.0 processor will follow the xsl:otherwise
branch. The
single-argument version of the function-available
function is used here, because that is the only version available
in XSLT 1.0. Under the rules of XSLT 1.0, the call on the
matches
function is not an error, because it is never
evaluated.
A stylesheet that is designed to use facilities in some future
XSLT version when they are available, but to fall back to
XSLT 2.0 or XSLT 3.0 capabilities when not, might be
written using code such as the following. This hypothesizes the
availability in some future version of a function pad
which pads a string to a fixed length with spaces:
<xsl:value-of select="pad(/doc/title, 10)" use-when="function-available('pad', 2)"/> <xsl:value-of select="concat(/doc/title, string-join( for $i in 1 to 10 - string-length(/doc/title) return ' ', ''))" use-when="not(function-available('pad', 2))"/>
In this case the two-argument version of function-available
is
used, because there is no requirement for this code to run under
XSLT 1.0.
If the function name used in a FunctionCallXP30 within an XPath expression identifies an extension function, then to evaluate the FunctionCallXP30, the processor will first evaluate each of the arguments in the FunctionCallXP30. If the processor has information about the datatypes expected by the extension function, then it may perform any necessary type conversions between the XPath datatypes and those defined by the implementation language. If multiple extension functions are available with the same name, the processor may decide which one to invoke based on the number of arguments, the types of the arguments, or any other criteria. The result returned by the implementation is returned as the result of the function call, again after any necessary conversions between the datatypes of the implementation language and those of XPath. The details of such type conversions are outside the scope of this specification.
[ERR XTDE1420] It is a dynamic error if the arguments supplied to a call on an extension function do not satisfy the rules defined for that particular extension function, or if the extension function reports an error, or if the result of the extension function cannot be converted to an XPath value.
Note:
Implementations may also provide mechanisms allowing extension functions to report recoverable dynamic errors, or to execute within an environment that treats some or all of the errors listed above as recoverable.
[ERR XTDE1425] When the containing element is processed with XSLT 1.0 behavior, it is a dynamic error to evaluate an extension function call if no implementation of the extension function is available.
Note:
When XSLT 1.0 behavior is not enabled, this is a static error [ERR XPST0017] XP30.
Note:
There is no prohibition on calling extension functions that have side-effects (for example, an extension function that writes data to a file). However, the order of execution of XSLT instructions is not defined in this specification, so the effects of such functions are unpredictable.
Implementations are not required to perform full validation of values returned by extension functions. It is an error for an extension function to return a string containing characters that are not permitted in XML, but the consequences of this error are implementation-defined. The implementation may raise an error, may convert the string to a string containing valid characters only, or may treat the invalid characters as if they were permitted characters.
Note:
The ability to execute extension functions represents a potential security weakness, since untrusted stylesheets may invoke code that has privileged access to resources on the machine where the processor executes. Implementations may therefore provide mechanisms that restrict the use of extension functions by untrusted stylesheets.
All observations in this section regarding the errors that can occur when invoking extension functions apply equally when invoking extension instructions.
An implementation may allow an
extension function to return an object that does not have any
natural representation in the XDM data model, whether as an atomic
value, a node, or a function item. For example, an
extension function sql:connect
might return an object
that represents a connection to a relational database; the
resulting connection object might be passed as an argument to calls
on other extension functions such as sql:insert
and
sql:select
.
The way in which such objects are represented in the type system
is implementation-defined. They might
be represented by a completely new datatype, or they might be
mapped to existing datatypes such as integer
,
string
, or anyURI
.
Used to control how a stylesheet behaves if a particular schema type is or is not available in the static context.
type-available
($type-name
as
xs:string
) as
xs:boolean
This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on namespaces, and schema definitions.
A schema type (that is, a simple type or a complex type) is said
to be available within an XPath expression if it is a type
definition that is present in the in-scope schema
typesXP30 for that expression (see
5.4.1 Initializing the Static
Context). This includes built-in types, types imported
using xsl:import-schema
, and
extension types defined by the implementation.
The value of the $type-name
argument must be a string containing a EQName. The EQName is
expanded into an expanded QName using the namespace
declarations in scope for the expression. If the value is an unprefixed
lexical QName, then the default namespace is used in the expanded
QName.
The function returns true if and only if there is an available
type whose name matches the value of the $type-name
argument.
[ERR XTDE1428] It is a dynamic error if the argument does not evaluate to a string that is a valid EQName, or if the value is a lexical QName with a prefix for which no namespace declaration is present in the static context. If the processor is able to detect the error statically (for example, when the argument is supplied as a string literal), then the processor may optionally signal this as a static error.
The type-available
function is
of limited use within an [xsl:]use-when
expression,
because the static context for the expression does not include any
user-defined types.
[Definition: The extension instruction mechanism allows namespaces to be designated as extension namespaces. When a namespace is designated as an extension namespace and an element with a name from that namespace occurs in a sequence constructor, then the element is treated as an instruction rather than as a literal result element.] The namespace determines the semantics of the instruction.
Note:
Since an element that is a child of an xsl:stylesheet
element is
not occurring in a sequence
constructor , user-defined data elements
(see 3.8.3 User-defined Data
Elements) are not extension elements as defined here, and
nothing in this section applies to them.
A namespace is designated as an extension namespace by using an
[xsl:]extension-element-prefixes
attribute on an
element in the stylesheet (see 3.5 Standard Attributes). The
attribute must be in the XSLT namespace
only if its parent element is not in the XSLT namespace.
The value of the attribute is a whitespace-separated list of
namespace prefixes. The namespace bound to each of the prefixes is
designated as an extension namespace.
The default namespace (as declared by xmlns
) may be
designated as an extension namespace by including
#default
in the list of namespace prefixes.
[ERR XTSE1430] It is a static error if there
is no namespace bound to the prefix on the element bearing the
[xsl:]extension-element-prefixes
attribute or, when
#default
is specified, if there is no default
namespace.
The designation of a namespace as an extension namespace is
effective for the element bearing the
[xsl:]extension-element-prefixes
attribute and for all
descendants of that element within the same stylesheet module.
Determines whether a particular instruction is or is not
available for use. The function is particularly useful for calling
within an [xsl:]use-when
attribute (see 3.14 Conditional Element
Inclusion) to test whether a particular extension instruction is
available.
element-available
($element-name
as
xs:string
) as
xs:boolean
This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on namespaces.
The value of the $element-name
argument
must be a string containing an EQName. If it is a
lexical QName with a prefix, the it is
expanded into an expanded QName using the namespace
declarations in the static context of the expression. If there is a
default namespace in scope, then it is used to expand an unprefixed
lexical QName.
If the resulting expanded QName is in the XSLT namespace, the function returns true if and only if the local name matches the name of an XSLT element that is defined in this specification and implemented by the XSLT processor.
If the expanded QName has a null namespace URI,
the element-available
function will return false.
If the expanded QName is not in the XSLT namespace, the function returns true if and only if the processor has an implementation available of an extension instruction with the given expanded QName. This applies whether or not the namespace has been designated as an extension namespace.
If the processor does not have an implementation of a particular extension instruction available, and such an extension instruction is evaluated, then the processor must perform fallback for the element as specified in 23.2.3 Fallback. An implementation must not signal an error merely because the stylesheet contains an extension instruction for which no implementation is available.
[ERR XTDE1440] It is a dynamic error if the argument does not evaluate to a string that is a valid EQName, or if the value is a lexical QName with a prefix for which no namespace declaration is present in the static context. If the processor is able to detect the error statically (for example, when the argument is supplied as a string literal), then the processor may optionally signal this as a static error.
For element names in the XSLT namespace:
Where conformance rules make some features of the specification
optional, for example the xsl:stream
element, this
function can be used (typically in a use-when
expression) to determine whether the feature is available in a
particular processor. It can also be useful to distinguish
processors that implement XSLT 3.0 from processors that implement
other (older or newer) versions of the specification, and to
distinguish full implementations from incomplete
implementations.
In earlier versions of this specification, element-available
was
defined to return true only for elements classified as
instructions. The distinction between instructions and other
elements, however, is sometimes rather technical, and in XSLT 3.0
the effect of the function has therefore been aligned to do what
its name might suggest.
If an instruction is recognized but offers no useful
functionality (for example, if the system has been configured for
security reasons so that xsl:evaluate
always raises an
error), then element-available
when
applied to that instruction should return
false.
For element names in other namespaces:
The result of the element-available
does
not depend on whether or not the namespace of the supplied
instruction name has been designated as an extension element
namespace; it tests whether the instruction would be available if
the namespace were designated as such.

<xsl:fallback>

</xsl:fallback>
The content of an xsl:fallback
element is a
sequence constructor, and when
performing fallback, the value returned by the xsl:fallback
element is the
result of evaluating this sequence constructor.
When not performing fallback, evaluating an xsl:fallback
element returns
an empty sequence: the content of the xsl:fallback
element is
ignored.
There are two situations where a processor performs fallback: when an extension instruction that is not available is evaluated, and when an instruction in the XSLT namespace, that is not defined in XSLT 3.0, is evaluated within a region of the stylesheet for which forwards compatible behavior is enabled.
Note:
Fallback processing is not invoked in other situations, for
example it is not invoked when an XPath expression uses
unrecognized syntax or contains a call to an unknown function. To
handle such situations dynamically, the stylesheet should call
functions such as system-property
and
function-available
to
decide what capabilities are available.
[ERR XTDE1450] When a processor performs
fallback for an extension instruction that is
not recognized, if the instruction element has one or more xsl:fallback
children, then
the content of each of the xsl:fallback
children
must be evaluated; it is a dynamic
error if it has no xsl:fallback
children.
Note:
This is different from the situation with unrecognized XSLT
elements. As explained in 3.11 Forwards
Compatible Processing, an unrecognized XSLT element
appearing within a sequence constructor is a
static error unless (a) forwards
compatible behavior is enabled, and (b) the instruction has an
xsl:fallback
child.
The output of a transformation is a set of one or more final result trees.
A final result tree can be created
explicitly, by evaluating an xsl:result-document
instruction. As explained in 2.4 Executing a
Transformation, a final result tree is also created
implicitly if no xsl:result-document
instruction is evaluated, or if the result of evaluating the
initial template is a non-empty
sequence.
The way in which a final result tree is delivered to an application is implementation-defined.
Serialization of final result trees is described further in 25 Serialization

<xsl:result-document
format? = { eqname }
href? = { uri }
validation? = "strict" | "lax" | "preserve" |
"strip"
type? = eqname
method? = { "xml" | "html" | "xhtml" | "text" |
eqname }
byte-order-mark? = { "yes" | "no" }
cdata-section-elements? = { eqnames }
doctype-public? = { string }
doctype-system? = { string }
encoding? = { string }
escape-uri-attributes? = { "yes" | "no" }
html-version? = { decimal }
include-content-type? = { "yes" | "no" }
indent? = { "yes" | "no" }
item-separator? = { string }
media-type? = { string }
normalization-form? = { "NFC" | "NFD" | "NFKC" | "NFKD"
| "fully-normalized" | "none" | nmtoken }
omit-xml-declaration? = { "yes" | "no" }
parameter-document? = { uri }
standalone? = { "yes" | "no" | "omit" }
suppress-indentation? = { eqnames }
undeclare-prefixes? = { "yes" | "no" }
use-character-maps? = eqnames
output-version? = { nmtoken
} >

</xsl:result-document>
The xsl:result-document
instruction is used to create a final result tree. The
content of the xsl:result-document
element is a sequence constructor for the
children of the document node of the tree. A document node is
created, and the sequence obtained by evaluating the sequence
constructor is used to construct the content of the document, as
described in 5.8.1
Constructing Complex Content. The tree rooted at this
document node forms the final result tree.
The xsl:result-document
instruction defines the URI of the result tree, and may optionally
specify the output format to be used for serializing this tree.
The effective value of the
format
attribute, if specified, must be a EQName. The value is expanded using
the namespace declarations in scope for the xsl:result-document
element. The resulting expanded QName must match the expanded QName of a named output definition in the stylesheet.
This identifies the xsl:output
declaration that will
control the serialization of the final result tree
(see 25 Serialization), if the
result tree is serialized. If the format
attribute is
omitted, the unnamed output definition is used to
control serialization of the result tree.
[ERR XTDE1460] It is a dynamic error if the
effective value of the
format
attribute is not a valid EQName, or if it does not
match the expanded QName of an output definition in the stylesheet.
If the processor is able to detect the error statically (for
example, when the format
attribute contains no curly
brackets), then the processor may
optionally signal this as a static error.
Note:
The only way to select the unnamed output definition
is to omit the format
attribute.
The parameter-document
attribute allows
serialization parameters to be supplied in an external document.
The external document must contain an
output:serialization-parameters
element with the
format described in
Section 3.1 Setting Serialization Parameters by Means of a Data
Model Instance SER30, and the
parameters are interpreted as described in that specification.
If present, the effective value of the URI supplied in the
parameter-document
attribute is dereferenced, after
resolution against the base URI of the
xsl:result-document
element if it is a relative
reference. If the location of the stylesheet at development time is
different from the deployed location, any relative reference should
be resolved against the deployed location. A serialization error
occurs if the result of dereferencing the URI is ill-formed or
invalid; but if no document can be found at the specified location,
the attribute may
be ignored.
A serialization parameter specified in the
parameter-document
takes precedence over a value
supplied directly as an attribute of xsl:result-document
,
which in turn takes precedence over a value supplied in the
selected output definition, except that the values of the
cdata-section-elements
and
suppress-indentation
attributes are merged in the same
way as when multiple xsl:output
declarations are
merged.
The attributes method
, byte-order-mark
cdata-section-elements
, doctype-public
,
doctype-system
, encoding
,
escape-uri-attributes
,
html-version
, indent
,
item-separator
, media-type
,
normalization-form
, omit-xml-declaration
,
standalone
,
suppress-indentation
,
undeclare-prefixes
, use-character-maps
,
and output-version
may be used to override attributes
defined in the selected output definition.
With the exception of use-character-maps
, these
attributes are all defined as attribute value
templates, so their values may be set dynamically. For any of
these attributes that is present on the xsl:result-document
instruction, the effective value of the attribute
overrides or supplements the corresponding value from the output
definition. This works in the same way as when one xsl:output
declaration overrides
another:
In the case of cdata-section-elements
and
suppress-indentation
, the value of the
serialization parameter is the union of the expanded names of the
elements named in this instruction and the elements named in the
selected output definition;
In the case of use-character-maps
, the character
maps referenced in this instruction supplement and take precedence
over those defined in the selected output definition;
In the case of doctype-public
and
doctype-system
, setting the effective value of the
attribute to a zero-length string has the effect of overriding any
value for these attributes obtained from the output definition. The
corresponding serialization parameter is not set (is "absent").
In the case of item-separator
, setting the
effective value of the attribute to the special value
"#absent"
has the effect of overriding any value for
this attribute obtained from the output definition. The
corresponding serialization parameter is not set (is "absent"). it
is not possible to set the value of the serialization parameter to
the literal 7-character string "#absent".
In all other cases, the effective value of an attribute actually present on this instruction takes precedence over the value defined in the selected output definition.
Note:
In the case of the attributes method
,
cdata-section-elements
,
suppress-indentation
, and
use-character-maps
, the effective value of
the attribute contains a space-separated list of EQNames. If any of these is a
lexical QName with a prefix, the prefix is
expanded using the in-scope namespaces for the
xsl:result-document
element. In the case of
cdata-section-elements
and
suppress-indentation
, an unprefixed element
name is expanded using the default namespace. In the case of the
method
attribute, if the method is not one of the
system-defined methods (xml, html, xhtml, text) then the expanded
name must have a non-absent namespace.
The output-version
attribute on the xsl:result-document
instruction overrides the version
attribute on
xsl:output
(it has been
renamed because version
is available with a different
meaning as a standard attribute: see 3.5 Standard Attributes). In all
other cases, attributes correspond if they have the same name.
There are some serialization parameters that apply to some
output methods but not to others. For example, the
indent
attribute has no effect on the
text
output method. If a value is supplied for an
attribute that is inapplicable to the output method, its value is
not passed to the serializer. The processor may validate the value of such an attribute, but is
not required to do so.
The item-separator
serialization parameter defined
in [XSLT and XQuery
Serialization] is not available in xsl:result-document
; it
is not applicable, because the sequence that is serialized by XSLT
is always a singleton document node. Formally therefore, the
serializer is invoked passing an empty string as the value of this
parameter.
The href
attribute is optional. The default value
is the zero-length string. The effective value of the
attribute must be a URI
Reference, which may be absolute or relative. There
may be implementation-defined
restrictions on the form of absolute URI that may be used, but the
implementation is not required to enforce
any restrictions. Any valid relative URI reference
must be accepted. Note that the
zero-length string is a valid relative URI
reference.
The base URI of the document node at the root of the final result tree is based on the
effective value of the href
attribute. If the effective value is a relative URI
reference, then it is resolved relative to the
base output URI. If the implementation
provides an API to access final result trees, then it must allow a final result tree to be identified by
means of this base URI.
Note:
The base URI of the final result tree is not necessarily the same thing as the URI of its serialized representation on disk, if any. For example, a server (or browser client) might store final result trees only in memory, or in an internal disk cache. As long as the processor satisfies requests for those URIs, it is irrelevant where they are actually written on disk, if at all.
Note:
It will often be the case that one final result tree contains links to another final result tree produced during the same transformation, in the form of a relative URI reference. The mechanism of associating a URI with a final result tree has been chosen to allow the integrity of such links to be preserved when the trees are serialized.
As well as being potentially significant in any API that provides access to final result trees, the base URI of the new document node is relevant if the final result tree, rather than being serialized, is supplied as input to a further transformation.
The optional attributes type
and
validation
may be used on the xsl:result-document
instruction to validate the contents of the new document, and to
determine the type annotation that elements and attributes
within the final result tree will carry. The
permitted values and their semantics are described in 24.2.2 Validating Document
Nodes.
A processor may allow a
final result tree to be serialized.
Serialization is described in 25
Serialization. However, an implementation (for example, a
processor running in an environment with no
access to writable filestore) is not required to support the serialization of final result trees. An implementation
that does not support the serialization of final result trees
may ignore the format
attribute and the serialization attributes. Such an implementation
must provide the application with some
means of access to the (un-serialized) result tree, using its URI
to identify it.
Implementations may provide additional mechanisms, outside the
scope of this specification, for defining the way in which
final result trees are processed. Such
mechanisms may make use of the
XSLT-defined attributes on the xsl:result-document
and/or xsl:output
elements, or they may use additional
elements or attributes in an implementation-defined
namespace.
The following example takes an XHTML document as input, and
breaks it up so that the text following each
 element is
included in a separate document. A new document
toc.html
is constructed to act as an index:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <xsl:output name="toc-format" method="xhtml" indent="yes" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"/> <xsl:output name="section-format" method="xhtml" indent="no" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/> <xsl:template match="/"> <xsl:result-document href="toc.html" format="toc-format" validation="strict">  <title>Table of Contents</title>
Table of Contents
 <xsl:for-each select="/*/xhtml:body/(*[1] | xhtml:h1)">
  <xsl:value-of select="."/>
 </xsl:for-each>   </xsl:result-document> <xsl:for-each-group select="/*/xhtml:body/*" group-starting-with="xhtml:h1"> <xsl:result-document href="section{position()}.html" format="section-format" validation="strip">  <title><xsl:value-of select="."/></title>  <xsl:copy-of select="current-group()"/>   </xsl:result-document> </xsl:for-each-group> </xsl:template> </xsl:stylesheet>
There are restrictions on the use of the xsl:result-document
instruction, designed to ensure that the results are fully
interoperable even when processors optimize the sequence in which
instructions are evaluated. Informally, the restriction is that the
xsl:result-document
instruction can only be used while writing a final result tree, not
while writing to a temporary tree or a sequence. This restriction
is defined formally as follows.
[Definition: Each instruction in the stylesheet is evaluated in one of two possible output states: final output state or temporary output state ].
[Definition: The first of the two output states is called final output state. This state applies when instructions are writing to a final result tree.]
[Definition: The second of the two output states is called temporary output state. This state applies when instructions are writing to a temporary tree or any other non-final destination.]
The instructions in the initial template are
evaluated in final output state. An instruction is
evaluated in the same output state as its calling instruction,
except that xsl:variable
, xsl:param
, xsl:with-param
, xsl:function
, xsl:key
, xsl:sort
, and xsl:merge-key
always
evaluate the instructions in their contained sequence constructor in temporary output state.
[ERR XTDE1480] It is a dynamic error to
evaluate the xsl:result-document
instruction in temporary output state.
[ERR XTDE1490] It is a dynamic error for a transformation to generate two or more final result trees with the same URI.
Note:
Note, this means that it is an error to evaluate more than one
xsl:result-document
instruction that omits the href
attribute, or to
evaluate any xsl:result-document
instruction that omits the href
attribute if an
initial final result tree is created
implicitly.
In addition, an implementation may report this error if it is able to detect that two or more final result trees are generated with different URIs that refer to the same physical resource.
Technically, the result of evaluating the xsl:result-document
instruction is an empty sequence. This means it does not contribute
any nodes to the result of the sequence constructor it is part
of.
[ERR XTDE1500] It is a dynamic error for a stylesheet to write to an external resource and read from the same resource during a single transformation, if the same absolute URI is used to access the resource in both cases.
In addition, an implementation may report this error if it is able to detect that a transformation writes to a resource and reads from the same resource using different URIs that refer to the same physical resource. Note that if the error is not detected, it is implementation-dependent whether the document that is read from the resource reflects its state before or after the result tree is written.
It is possible to control the type annotation applied to
individual element and attribute nodes as they are constructed.
This is done using the type
and
validation
attributes of the xsl:element
, xsl:attribute
, xsl:copy
, xsl:copy-of
, xsl:document
, and xsl:result-document
instructions, or the xsl:type
and
xsl:validation
attributes of a literal result element.
The [xsl:]type
attribute is used to request
validation of an element or attribute against a specific simple or
complex type defined in a schema. The [xsl:]validation
attribute is used to request validation against the global element
or attribute declaration whose name matches the name of the element
or attribute being validated.
The [xsl:]type
and [xsl:]validation
attributes are mutually exclusive. Both are optional, but if one is
present then the other must be omitted.
If both attributes are omitted, the effect is the same as
specifying the validation
attribute with the value
specified in the [xsl:]default-validation
attribute of the innermost containing element having such an
attribute; if this is not specified, the effect is the same
as specifying validation="strip"
.
The [xsl:]default-validation
attribute defines the
default value of the validation
attribute of all
xsl:element
, xsl:attribute
, xsl:copy
, xsl:copy-of
, xsl:document
, and xsl:result-document
instructions, and of the xsl:validation
attribute of
all literal result elements ,
appearing within its scope. It also determines the
validation applied to the implicit final result tree
created in the absence of an xsl:result-document
instruction. This default applies within the containing stylesheet module or package: it does not extend
to included or imported stylesheet modules or used packages. If the
attribute is omitted, the default is strip
. The
permitted values are preserve
and
strip
.
[ERR XTSE1505] It is a static error if both
the [xsl:]type
and [xsl:]validation
attributes are present on the xsl:element
, xsl:attribute
, xsl:copy
, xsl:copy-of
, xsl:document
, or xsl:result-document
instructions, or on a literal result
element.
The detailed rules for validation vary depending on the kind of node being validated. The rules for element and attribute nodes are given in 24.2.1 Validating Constructed Elements and Attributes, while those for document nodes are given in 24.2.2 Validating Document Nodes.
[xsl:]validation
AttributeThe [xsl:]validation
attribute defines the
validation action to be taken. It determines not only the type
annotation of the node that is constructed by the relevant
instruction itself, but also the type annotations of all element
and attribute nodes that have the constructed node as an ancestor.
Conceptually, the validation requested for a child element or
attribute node is applied before the validation requested for its
parent element. For example, if the instruction that constructs a
child element specifies validation="strict"
, this will
cause the child element to be checked against an element
declaration, but if the instruction that constructs its parent
element specifies validation="strip"
, then the final
effect will be that the child node is annotated as
xs:untyped
.
In the paragraphs below, the term contained nodes means the elements and attributes that have the newly constructed node as an ancestor.
The value strip
indicates that the new node and
each of the contained nodes will have the type
annotation xs:untyped
if it is an element, or
xs:untypedAtomic
if it is an attribute. Any previous
type annotation present on a contained element or attribute node
(for example, a type annotation that is present on an element
copied from a source document) is also replaced by
xs:untyped
or xs:untypedAtomic
as
appropriate. The typed value of the node is changed to be the same
as its string value, as an instance of
xs:untypedAtomic
. In the case of elements the
nilled
property is set to false
. The
values of the is-id
and is-idrefs
properties are unchanged. Schema validation is not invoked.
The value preserve
indicates that nodes that are
copied will retain their type annotations, but nodes whose content
is newly constructed will be annotated as xs:anyType
in the case of elements, or xs:untypedAtomic
in the
case of attributes. Schema validation is not invoked. The detailed
effect depends on the instruction:
In the case of xsl:element
and literal result
elements, the new element has a type annotation of
xs:anyType
, and the type annotations of contained
nodes are retained unchanged.
In the case of xsl:attribute
, the effect is
exactly the same as specifying validation="strip"
: