Copyright © 1998 W3C (MIT, INRIA, Keio ), All Rights Reserved. W3C liability,trademark, document use and software licensing rules apply.
XSLT is a language for transforming XML documents into other XML documents.
XSLT is designed for use as part of XSL, which is a stylesheet language for XML. In addition to XSLT, XSL includes an XML vocabulary for specifying formatting. XSL specifies the styling of an XML document by using XSLT to describe how the document is transformed into another XML document that uses the formatting vocabulary.
XSLT is also designed to be used independently of XSL. However, XSLT is not intended as a completely general-purpose XML transformation language. Rather it is designed primarily for the kinds of transformation that are needed when XSLT is used as part of XSL.
This is a W3C Working Draft for review by W3C members and other interested parties. It is a draft document and may be updated, replaced, or obsoleted by other documents at any time. The material in this draft was previously part of the XSL Working Draft. The XSL Working Group will not allow early implementation to constrain its ability to make changes to this specification prior to final release. It is inappropriate to use W3C Working Drafts as reference material or to cite them as other than "work in progress". A list of current W3C working drafts can be found at http://www.w3.org/TR.
This draft is intended to be "feature complete". The Working Group plans to use future drafts to stabilize the current functionality; it does not intend to add any new functionality in version 1.0.
The XSL WG and the XML Linking WG have agreed to unify XSLT expressions and XPointers [XPointer]. A common core semantic model for querying has been agreed upon, and this draft follows this model (see [6.1 Location Paths]). However, further changes particularily in the syntax will probably be necessary.
This is part of the Style activity.
Comments may be sent to xsl-editors@w3.org; archives of the comments are available. Public discussion of XSL, including XSL Transformations, takes place on the XSL-List mailing list.
A transformation expressed in XSLT describes rules for transforming a source tree into a result tree. The transformation is achieved by associating patterns with templates. A pattern is matched against elements in the source tree. A template is instantiated to create part of the result tree. The result tree is separate from the source tree. The structure of the result tree can be completely different from the structure of the source tree. In constructing the result tree, elements from the source tree can be filtered and reordered, and arbitrary structure can be added.
A transformation expressed in XSLT is called a stylesheet. This is because, in the case when XSLT is transforming into the XSL formatting vocabulary, the transformation functions as a stylesheet.
This document does not specify how an XSLT stylesheet is associated with an XML document. It is recommended that XSL processors support the mechanism described in [XML Stylesheet].
A stylesheet contains a set of template rules. A template rule has two parts: a pattern which is matched against nodes in the source tree and a template which can be instantiated to form part of the result tree. This allows a stylesheet to be applicable to a wide class of documents that have similar source tree structures.
A template is instantiated for a particular source element to create part of the result tree. A template can contain elements that specify literal result element structure. A template can also contain elements that are instructions for creating result tree fragments. When a template is instantiated, each instruction is executed and replaced by the result tree fragment that it creates. Instructions can select and process descendant source elements. Processing a descendant element creates a result tree fragment by finding the applicable template rule and instantiating its template. Note that elements are only processed when they have been selected by the execution of an instruction. The result tree is constructed by finding the template rule for the root node and instantiating its template.
In the process of finding the applicable template rule, more than one template rule may have a pattern that matches a given element. However, only one template rule will be applied. The method for deciding which template rule to apply is described in [7.4 Conflict Resolution for Template Rules].
XSLT uses XML namespaces [XML Names] to distinguish
elements that are instructions to the XSLT processor from elements that
specify literal result tree structure. Instruction elements all
belong to the XSLT namespace. The examples in this document use a
prefix of xsl: for elements in the XSLT namespace.
XSLT includes an expression language (see [6 Expressions and Patterns]) that is used for selecting elements for processing, for conditional processing and for generating text. The expression language is not a complete programming language. XSLT provides an extension mechanism to allow access from the expression language to a complete programming language such as ECMAScript or Java. XSLT does not require support for any programming language. Therefore XSLT stylesheets that must be portable across all XSLT implementations cannot depend on this extension mechanism.
A stylesheet is represented by an xsl:stylesheet
element in an XML document. xsl:transform is allowed as
a synonym for xsl:stylesheet.
XSLT processors must use the XML namespaces mechanism [XML Names] for both source documents and stylesheets. All XSLT
defined elements, that is those specified in this document with a
prefix of xsl:, will only be recognized by the XSLT
processor if they belong to a namespace with the URI
http://www.w3.org/XSL/Transform/1.0; XSLT defined
elements are recognized only in the stylesheet not in the source
document.
The xsl:stylesheet element may contain the following types
of elements:
xsl:import
xsl:include
xsl:strip-space
xsl:preserve-space
xsl:key
xsl:functions
xsl:locale
xsl:attribute-set
xsl:variable
xsl:param-variable
xsl:template
This example shows the structure of a stylesheet. Ellipses
(...) indicate where attribute values or content have
been omitted. Although this example shows one of each type of allowed
element, stylesheets may contain zero or more of each of these
elements.
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0">
<xsl:import href="..."/>
<xsl:include href="..."/>
<xsl:strip-space elements="..."/>
<xsl:preserve-space elements="..."/>
<xsl:key name="..." match="..." use="..."/>
<xsl:functions ns="...">
...
</xsl:functions>
<xsl:locale name="...">
...
</xsl:locale>
<xsl:attribute-set name="...">
...
</xsl:attribute-set>
<xsl:variable name="...">...</xsl:variable>
<xsl:param-variable name="...">...</xsl:param-variable>
<xsl:template match="...">
...
</xsl:template>
<xsl:template name="...">
...
</xsl:template>
</xsl:stylesheet>
The order in which the children of the xsl:stylesheet
element occur is not significant except for xsl:import
elements and for error recovery. Users are free to order the elements
as they prefer, and stylesheet creation tools need not provide control
over the order in which the elements occur.
An XSLT processor must treat any namespace whose URI starts with
the http://www.w3.org/XSL/Transform/ in the same way as
the XSLT 1.0 namespace
(http://www.w3.org/XSL/Transform/1.0) except that it must
recover from errors as follows:
Unrecognized attributes on elements in the XSLT namespace must be ignored
Unrecognized top-level XSLT elements must be ignored along with their content
Error reporting for unrecognized XSLT elements in templates must be lazy: in other words it's not an error to have an unrecognized XSLT element unless the element is actually instantiated
Similarly error reporting for bad expression syntax must be lazy: it's not an error to have bad expression syntax in an attribute on some element unless the element containing the bad syntax is instantiated
Ed. Note: What happens with stylesheets that mix XSLT namespaces with different versions?
Thus any XSLT 1.0 processor must be able to process the following stylesheet without error:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.1">
<xsl:template name="/">
<xsl:choose>
<xsl:when test="system-property('xsl:version') >= 1.1">
<xsl:exciting-new-1.1-feature/>
</xsl:when>
<xsl:otherwise>
<p>Sorry this stylesheet requires XSLT 1.1.</p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
XSLT operates on an XML document, whether a stylesheet or a source document, as a tree. Any two stylesheets or source documents that have the same tree will be processed the same by XSLT. The XML document resulting from the tree construction process is also a tree. This section describes how XSLT models an XML document as a tree. This model is conceptual only and does not mandate any particular implementation.
XML documents operated on by XSLT must conform to the XML namespaces specification [XML Names].
The tree contains nodes. There are seven kinds of node:
root nodes
element nodes
text nodes
attribute nodes
namespace nodes
processing instruction nodes
comment nodes
Neither processing instruction nodes nor comment nodes are included in the tree for the stylesheet.
For every type of node there is a way of determining a string value for a node of that type. For some types of node, the value is part of the node; for other types of node, the value is computed from the value of descendant nodes.
Issue (data-entity): Should XSLT provide support for external data entities and notations?
Issue (entity-ref): Should XSLT provide support for entity references?
Issue (dtd): Should XSLT provide support for DTDs in the data model?
The root node is the root of the tree. It does not occur anywhere else in the tree. It has a single child which is the element node for the document element of the document.
The value of the root node is the value of the document element.
There is an element node for every element in the document. An element has an expanded name consisting of a local name and a possibly null URI reference (see [XML Names]); the URI reference will be null if the element type name has no prefix and there is no default namespace in scope. A relative URI reference should be resolved into an absolute URI during namespace processing.
The children of an element node are the element nodes, comment nodes, processing instruction nodes and text nodes for its content. Entity references to both internal and external entities are expanded. Character references are resolved.
The descendants of an element node are the children of the element node and the descendants of the children that are element nodes.
The value of an element node is the string that results from concatenating all characters that are descendants of the element node in the order in which they occur in the document.
The set of all element nodes in a document can be ordered according to the order of the start-tags of the elements in the document; this is known as document order.
Ed. Note: Need a definition of document order that handles arbitrary node types, including attributes.
An element object may have a unique identifier (ID). This is the
value of the attribute which is declared in the DTD as type
ID. No two elements in a document may have the same
unique ID. If an XML processor reports two elements in a document as
having the same unique ID (which is possible only if the document is
invalid) then the second element must be treated as not having a
unique ID.
NOTE: If a document does not have a DTD, then no element in the document will have a unique ID.
An element node also has an associated URI called its base URI which is used for resolving attribute values that represent relative URIs into absolute URIs. If an element occurs in an external entity, the base URI of that element is the URI of the external entity. Otherwise the base URI is the base URI of the document.
Each element node has an associated set of attribute nodes. A
defaulted attribute is treated the same as a specified attribute. If
an attribute was declared for the element type in the DTD, but the
default was declared as #IMPLIED, and the attribute was
not specified on the element, then the element's attribute set does
not contain a node for the attribute.
An attribute node has an expanded name and has a string value. The expanded name consists of a local name and a possibly null URI (see [XML Names]); the URI will be null if the specified attribute name did not have a prefix. The value is the normalized value as specified by the XML Recommendation [XML]. An attribute whose normalized value is a zero-length string is not treated specially: it results in an attribute node whose value is a zero-length string.
There are no attribute nodes for attributes that declare namespaces (see [XML Names]).
Issue (external-dtd): Should we specify something about how we expect XSLT processors to process external DTDs and parameter entities? For example, what happens if an attribute default is declared in an external DTD?
Each element has an associated set of namespace nodes, one for each namespace prefix that is in scope for the element and one for the default namespace if one is in scope for the element. This means that an element will have a namespace node:
for every attribute on the element whose name starts with
xmlns:;
for every attribute on an ancestor element whose name starts
xmlns: unless the element itself or a nearer ancestor
redeclares the prefix;
for an xmlns attribute, unless its value is the empty
string.
NOTE: An attribute xmlns="" "undeclares"
the default namespace (see [XML Names]).
A namespace node has a name which is a string giving the prefix. This is empty if the namespace node is for the default namespace. A namespace node also has a value which is the namespace URI. If the namespace declaration specifies a relative URI, then the resolved absolute URI is used as the value.
When writing an element node in the result tree out as XML, an XSLT processor must add sufficient namespace-declaring attributes to the start-tag to ensure that if a tree were recreated from the XML, then the set of namespace nodes on the element node in the recreated tree would be equal to or a superset of the set of namespace nodes of the element node in the result tree.
NOTE: The semantics of a document type may treat parts of attribute values or data content as namespace prefixes. The presence of namespace nodes ensures that the semantics can be preserved when the tree is written out as XML.
There is a processing instruction node for every processing instruction.
Ed. Note: What about processing instructions in the internal subset or elsewhere in the DTD?
A processing instruction has a name. This is a string equal to
the processing instruction's target. It also has a value. This is a
string equal to the part of the processing instruction following the
target and any whitespace. It does not include the terminating
?>.
There is a comment node for every comment.
Ed. Note: What about comments in the internal subset or elsewhere in the DTD?
A comment has a value. This is a string equal to the text of the
comment not including the opening <!-- or the closing
-->.
Character data is grouped into text nodes. As much character data as possible is grouped into each text node: a text node never has an immediately following or preceding sibling that is a text node. The value of a text node is the character data.
Each character within a CDATA section is treated as character data.
Thus <![CDATA[<]]> in the source document will
treated the same as <. Both will result in a
single < character in a text node in the tree.
NOTE: When a text node that contains a<character is written out as XML, the<character must be escaped by, for example, using<, or including it in a CDATA section.
Characters inside comments or processing instructions are not character data. Line-endings in external entities are normalized to #xA as specified in the XML Recommendation [XML].
After the tree has been constructed, but before it is otherwise processed by XSLT, some text nodes may be stripped. The stripping process takes as input a set of element types for which whitespace must be preserved. The stripping process is applied to both stylesheets and source documents, but the set of whitespace-preserving element types is determined differently for stylesheets and for source documents.
A text node is preserved if any of the following apply:
The element type of the parent of the text node is in the set of whitespace-preserving element types.
The text node contains at least one non-whitespace character. As in XML, a whitespace character is #x20, #x9, #xD or #xA.
An ancestor element of the text node has an
xml:space attribute with a value of
preserve, and no closer ancestor element has
xml:space with a value of
default.
Otherwise the text node is stripped.
The xml:space attributes are not stripped from the
tree.
NOTE: This implies that if an xml:space attribute is
specified on a literal result element, it will be included in the
result.
For stylesheets, the set of whitespace-preserving element types
consists of just xsl:text.
For source documents, the set of whitespace-preserving element types is determined using the stylesheet as follows:
If the xsl:stylesheet element specifies a
default-space attribute with a value of
strip, then the set is initially empty. Otherwise the
set initially contains all element types that occur in the
document.
The xsl:strip-space element causes element types
to be removed from the set of whitespace-preserving element types.
The elements attribute gives a white-space separated list
of the names of the element types.
The xsl:preserve-space element causes element
types to be added to the set of whitespace-preserving element
types. The elements attribute gives a white-space
separated list of the names of the element types.
Ed. Note: Clarify how these declarations interact with each other and with xsl:import.
The xsl:stylesheet element has an optional
result-ns attribute; the value must be a namespace
prefix. If there is a namespace declared as the default namespace,
then an empty string may be used as the value to specify that the
default namespace is the result namespace.
The result-ns attribute is a hint to the XSLT
processor that it should do something with the result tree other than
simply output it as XML. XSLT processors are not required to pay
attention to the hint and may simply output the result tree as XML.
If the result-ns attribute is not specified, then the
result tree must be output as XML. If the result-ns
attribute is specified, all elements in the result tree must belong to
the namespace identified by this prefix (the result
namespace).
When an XSLT processor outputs the result tree as a sequence of bytes that represents the result tree in XML, it must do so in such a way that the sequence of bytes is a well-formed XML document conforming to the XML Namespaces Recommendation [XML Names] and that if a new tree was constructed from the sequence of bytes as specified in [4 Data Model], the new tree would be the same as the result tree, with the following possible exceptions:
The order of attributes in the two trees may be different.
The new tree may contain namespace nodes that were not present in the result tree.
NOTE: An XSLT processor may need to add namespace declarations in the course of outputting the result tree as XML.
A result namespace of http://www.w3.org/XSL/Format/1.0
indicates that the result tree should be interpreted according to the
semantics defined in [XSL]. XSL requires that XSL
processors respect this hint. The examples in this document use the
fo: prefix for this namespace.
A result namespace of http://www.w3.org/TR/REC-html40
indicates that the result tree should be output as HTML that conforms
to the HTML 4.0 Recommendation rather than as XML; for example,
<xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0" xmlns="http://www.w3.org/TR/REC-html40" result-ns=""> <xsl:template match="/"> <html> <xsl:apply-templates/> </html> </xsl:template> ... </xsl:stylesheet>
The xsl:stylesheet element can include an
indent-result attribute with values yes or
no. If the stylesheet specifies
indent-result="yes", then the XSLT processor may add
whitespace to the result tree (possibly based on whitespace stripped
from either the source document or the stylesheet) in order to indent
the result nicely; if indent-result="no", it must not add
any whitespace to the result. When adding whitespace with
indent-result="yes", the XSLT processor can use any
algorithm provided that the result is the same as the result with
indent-result="no" after whitespace is stripped from both
using the process described with the set of whitespace-preserving
element types consisting of just xsl:text.
Ed. Note: The XSL WG and the XML Linking WG have agreed to unify XSLT expressions and XPointers. A common core semantic model for querying has been agreed upon, and this draft follows this model. However, further changes particularily in the syntax will probably be necessary.
Expressions are used in XSLT for a variety of purposes including:
An expression is evaluated to yield an object which has one of the following types:
Expression evaluation occurs with respect to a context, which consists of:
The context node is always a member of the context node list. The variable bindings consist of a mapping from variable names to variable values. The value of a variable is an object which can have any of the types which are possible for the value of an expression.
The variable bindings, node key function, extension functions and namespace declarations used to evaluate a subexpression are always the same as those used to evaluate the containing expression. The context node and context node list used to evaluate a subexpression is sometimes different from the context node and context node list used to evaluate the containing expression. When the evaluation of a kind of expression is described, it will always be explicitly stated if the context node and node list change for the evaluation of subexpressions; if nothing is said about the context node and context node list, they remain unchanged for the evaluation of subexpressions of that kind of expression.
The node key function takes a pair of strings (a key name and a key value) and a document and returns a set of nodes (the nodes in the document that have a key with the specified name and value).
In XSLT, expressions occur in attribute values. The grammar
specified in this section applies to the attribute value after XML 1.0
normalization. So, for example, if the grammar uses the character
< this must not appear in the XML source for the
stylesheet as < but must be quoted according to XML
1.0 rules by, for example, entering it as <.
A top-level expression (an expression not occurring within an expression) gets its context as follows:
the context node comes from the current node
the context node list comes from the current node list
the variable bindings are the bindings in scope on the element which has the attribute in which the expression occurs (see [13 Variables and Parameters])
the node key function is specified by top-level
xsl:key elements (see [6.4.1 Declaring Keys])
the implementations of extension functions are provided by
top-level xsl:functions elements (see [6.4.2 Declaring Extension Functions]), and may also be provided externally to the
stylesheet by means not specified by XSLT
the set of namespace declarations are those in scope on the
element which has the attribute in which the expression occurs; the default
namespace (as declared by xmlns) is not part of this
set
One important kind of expression is a location path. A location path selects a set of nodes relative to the context node. The result of evaluating an expression that is a location path is the node-set containing the nodes selected by the location path. Location paths can recursively contain expressions which are used to filter lists of nodes.
Certain contexts in XSLT make use of a pattern. A pattern specifies a set of conditions on a node. A node that satisfies the conditions matches the pattern; a node that does not satisfy the conditions does not match the pattern. The syntax for patterns is a subset of the syntax for expressions. In particular location paths that meet certain restrictions can be used as patterns. An expression that is also a pattern always evaluates to an object of type node-set. A node matches a pattern if the node is a member of the result of evaluating the pattern as an expression with respect to some possible context; the possible contexts are those whose context node is the node being matched or one of its ancestors.
In the following grammar, the nonterminals QName and NCName are defined in [XML Names], and S is defined in [XML].
Expressions (including patterns and location paths) are parsed by first dividing up the character string to be parsed into tokens and then parsing the resulting sequence of tokens. Whitespace can be freely used between tokens. The tokenization process is described in [6.2.9 Lexical Structure].
Every location path can be expressed using a straightforward but rather verbose syntax. There are also a number of syntactic abbreviations that allow common cases to be expressed concisely. This section will explain the semantics of location paths using the unabbreviated syntax. The abbreviated syntax will then be explained by showing how it expands into the unabbreviated syntax (see [6.1.4 Abbreviated Syntax]).
Here are some examples of location paths using the unabbreviated syntax:
from-children(para) selects the
para element children of the context node
from-children(*) selects all element
children of the context node
from-children(text()) selects all text
node children of the context node
from-children(node()) selects all the
children of the context node, whatever their node type
from-attributes(name) selects the
name attribute of the context node
from-attributes(*) selects all the
attributes of the context node
from-descendants(para) selects the
para element descendants of the context node
from-ancestors(div) selects all div
ancestors of the context node
from-ancestors-or-self(div) selects the
div ancestors of the context node and, if the context node is a
div element, the context node as well
from-descendants-or-self(para) selects the
para element descendants of the context node and, if the context node is
a para element, the context node as well
from-self(para) selects the context node if it is a
para element, and otherwise selects nothing
from-children(chapter)/from-descendants(para)
selects the para element descendants of the
chapter element children of the context node
from-children(*)/from-children(para) selects
all para grandchildren of the context node
/ selects the document root (which is
always the parent of the document element)
/from-descendants(para) selects all the
para elements in the same document as the context node
/from-descendants(olist)/from-children(item)
selects all the item elements in the same document as the
context node that have an olist parent
from-children(para[position()=1]) selects the first
para child of the context node
from-children(para[position()=last()]) selects the last
para child of the context node
from-children(para[position()=last()-1]) selects
the last but one para child of the context node
from-children(para[position()>1]) selects all
the para children of the context node other than the
first para child of the context node
from-following-siblings(chapter[position()=1])
selects the next chapter sibling of the context node
from-preceding-siblings(chapter[position()=1])
selects the previous chapter sibling of the
context node
/from-descendants(figure[position()=42]) selects
the forty-second figure element in the
document
/from-children(doc)/from-children(chapter[position()=5])/from-children(section[position()=2])
selects the second section of the fifth
chapter of the doc document element
from-children(para[from-attributes(type)="warning"])
selects all para children of the context node that have a
type attribute with value warning
from-children(para[from-attributes(type)="warning"][position()=5])
selects the fifth para child of the context node that has a
type attribute with value warning
from-children(para[position()=5][from-attributes(type)="warning"])
selects the fifth para child of the context node if that child has
a type attribute with value
warning
from-children(chapter[from-children(title)="Introduction"])
selects the chapter children of the context node whose first
title child has value equal to
Introduction
from-children(chapter[from-children(title)])
selects the chapter children of the context node that have one
or more title children
from-children(chapter[from-children(title[from-self(*)="Introduction"])])
selects the chapter children of the context node any of whose
title children has value equal to
Introduction
from-children(*[from-self(chapter) or
from-self(appendix)]) selects the chapter and
appendix children of the context node
from-children(*[from-self(chapter) or
from-self(appendix)][position()=last()]) selects the last
chapter or appendix child of the
context node
There are two kinds of location path: relative location paths and absolute location paths.
A relative location path consists of a sequence of one or more
location steps separated by /. The steps in a relative
location path are composed together from left to right. Each step in
turn selects a set of nodes relative to a context node. An initial
sequence of steps is composed together with a following step as
follows. The initial sequence of steps selects a set of nodes
relative to a context node. Each node in that set is used as a
context node for the following step. The sets of nodes identified by
the second step are unioned together. The set of nodes identified by
the composition of the steps is this union. For example,
from-children(div)/from-children(para) selects the
para element children of the div element
children of the context node, or, in other words, the
para element grandchildren that have div
parents.
An absolute location path consists of / optionally
followed by a relative location path. A / by itself
selects the root node of the document containing the context node. If
it is followed by a relative location path, then the location path
selects the set of nodes that would be selected by the relative
location path relative to the root node of the document containing the
context node.
A location step consists of
an axis identifier;
a node test;
zero or more predicates.
The axis identifier selects an initial list of nodes relative to the context node. The initial list of nodes is filtered first by the node test; the result of filtering by the node test is then filtered by the first predicate; the result of that is then filtered by the next predicate and so on. The node test selects nodes from the initial list based on the node type and node name. Each predicate selects nodes that satisfy a condition specified by an arbitrary expression. The result of the location step is the set of nodes that are members of the list that results from filtering the initial list by the node test and all the predicates. Note that although a location step selects a set of nodes, an axis selects a list of nodes and the predicates operate on a list of nodes.
The axis identifier is followed by the node test and predicates in
parentheses. For example, from-descendants(para) selects the
descendants of the context node that are para elements:
from-descendants specifies the axis, and para
is a test that is true for elements with name para. Each
predicate is specified as an expression in square brackets.
| [1] | LocationPath | ::= | RelativeLocationPath | |
| | AbsoluteLocationPath | ||||
| [2] | AbsoluteLocationPath | ::= | '/' RelativeLocationPath? | |
| | AbbreviatedAbsoluteLocationPath | ||||
| [3] | RelativeLocationPath | ::= | Step | |
| | RelativeLocationPath '/' Step | ||||
| | AbbreviatedRelativeLocationPath | ||||
| [4] | Step | ::= | AxisIdentifier '(' NodeTest Predicate* ')' | |
| | AbbreviatedStep |
An axis identifies a list of nodes based on the kind of tree relationship that the nodes have to the context node. For example, the children of the context node are one axis, the ancestors of the context node are another axis. Note that an axis identifies an ordered list, not a set. The order of nodes in an axis is in the direction away from the context node.
The following axes are defined:
the children axis contains the children of the
context node in document order
the descendants axis contains the descendants of
the context node in document order
the parent axis contains the parent of the
context node, if there is one
Ed. Note: Is the parent of an attribute node the element that the attribute is on?
the following-siblings axis contains the
following siblings of the context node in document order
the preceding-siblings axis contains the
preceding siblings of the context node in reverse document order; the first
preceding sibling is first on the axis; the sibling preceding that
node is the second on the axis and so on.
the following axis contains all nodes in the same
document as the context node that are after the context node in document order;
the nodes are ordered in document order
Issue (following-axis): Is the
followingaxis needed?
Issue (following-start): Should the
followingaxis include the descendants of the context node?
the preceding axis contains all nodes in the same
document as the context node that are before the context node in document order;
the nodes are ordered in reverse document order
Issue (preceding-axis): Is the
precedingaxis needed?
the ancestors axis contains the ancestors of the
context node; the nodes are ordered in reverse document order; thus the
parent is the first node on the axis, and the parent's parent is the
second node on the axis
the attributes axis contains the attributes of
the context node; the order of nodes on this axis is
implementation-defined
the self axis contains just the context node
itself
the ancestors-or-self axis contains the context node
and ancestors of the context node in reverse document order; thus the context node
is the first node on the axis, and the context node's parent the
second
the descendants-or-self axis contains the context node
and the descendants of the context node in document order; thus the context node
is the first node on the axis, and the first child of the context node is
the second node on the axis
In an axis identifier the name of the axis is preceded by
from- to distinguish it from a function name.
A node test that is a QName tests whether the node is an
element or attribute with the specified name. For example,
from-attributes(href) selects the href
attribute of the context node; if the context node has no href
attribute, it will select an empty set of nodes.
A QName in the node test
is expanded into a local name and a possibly null URI. This expansion
is done using the namespace declarations from the expression context.
This is the same way expansion is done for element type names in start
and end-tags except that the default namespace declared with
xmlns is not used: if the QName does not have a prefix, then
the URI is null (this is the same way attribute names are expanded).
The expanded names are then compared for equality. Two expanded names
are equal if they have the same local part, and either both have no
URI or both have the same URI.
A node test * is true for any element or
attribute node. For example, from-children(*) will
select all element children of the context node, and
from-attributes(*) will select all attributes of the
context node.
A node test can have the form NCName:*. In this case the
prefix is expanded in the same way as with a QName using the context namespace
declarations. The node test will be true for an element or attribute
whose expanded name has the URI to which the prefix expands, whatever
the local part of the name.
The node test text() is true for any text node. For
example from-children(text()) will select the text node
children of the context node. Similarly, the node test
comment() is true for any comment node, and the node test
pi() is true for any processing instruction. The
pi() test may have an argument that is Literal; in this case it is true for any
processing instruction that has a name equal to the value of the Literal.
A node test node() is true for any node.
| [6] | NodeTest | ::= | WildcardName | |
| | NodeType '(' ')' | ||||
| | 'pi' '(' Literal ')' |
A predicate filters a list of nodes to produce a new list of nodes. For each node in the list to be filtered, the PredicateExpr is evaluated with that node as the context node and with the complete list of nodes to be filtered as the context node list; if PredicateExpr evaluates to true for that node, the node is included in the new list; otherwise it is not included.
A PredicateExpr is evaluated by
evaluating the Expr and converting the result
to a boolean. If the result is a number, the result will be converted
to true if the number is equal to the position of the context node in
the context node list and will be converted to false otherwise; if the
result is not a number, then the result will be converted as if by a
call to the boolean() function. Thus a location path
para[3] is equivalent to para[position()=3].
| [7] | Predicate | ::= | '[' PredicateExpr ']' | |
| [8] | PredicateExpr | ::= | Expr |
Here are some examples of location paths using abbreviated syntax:
para selects the para element children of
the context node
* selects all element children of the
context node
text() selects all text node children of the
context node
@name selects the name attribute of
the context node
@* selects all the attributes of the
context node
para[1] selects the first para child of
the context node
para[last()] selects the last para child
of the context node
*/para selects all para grandchildren of
the context node
/doc/chapter[5]/section[2] selects the second
section of the fifth chapter of the
doc
chapter//para selects the para element
descendants of the chapter element children of the
context node
//para selects all the para descendants of
the document root and thus selects all para elements in the
same document as the context node
//olist/item selects all the item
elements in the same document as the context node that have an
olist parent
. selects the context node
.//para selects the para element
descendants of the context node
.. selects the parent of the context node
../@lang selects the lang attribute
of the parent of the context node
para[@type="warning"] selects all para
children of the context node that have a type attribute with
value warning
para[@type="warning"][5] selects the fifth
para child of the context node that has a type
attribute with value warning
para[5][@type="warning"] selects the fifth
para child of the context node if that child has a
type attribute with value warning
chapter[title="Introduction"] selects the
chapter children of the context node whose first
title child has value equal to
Introduction
chapter[title] selects the chapter
children of the context node that have one or more title
children
chapter[title[.="Introduction"]] selects the
chapter children of the context node any of whose
title children has value equal to
Introduction
employee[@secretary and @assistant] selects all
the employee children of the context node that have both a
secretary attribute and an assistant
attribute
The most important abbreviation is that when the axis is the
children axis, the from-children and surrounding
parentheses can be omitted. In effect the children axis
is the default axis. For example, a location path div/para
is short for from-children(div)/from-children(para).
There's also an abbreviation for the attributes axis. Instead of
using from-attributes and parentheses around the node
test, the node test can be preceded by @ to indicate the
attributes axis. For example, a location path
para[@type="warning"] is short for
from-children(para[from-attributes(type)="warning"]) and
so selects para children with a type
attribute with value equal to warning.
// is short for
/from-descendants-or-self(node())/. For example,
//para is short for
/from-descendants-or-self(node())/from-children(para) and so
will select any para element in the document (even a
para element that is a document element will be selected by
//para since the document element node is a child of the
root node); div//para is short for
div/from-descendants-or-self(node())/from-children(para) and
so will select all para descendants of div
children.
A location step of . is short for
from-self(node()). This is particularly useful in
conjunction with //. For example, the location path
.//para is short for
from-self(node())/from-descendants-or-self(node())/from-children(para)
and so will select all para descendant elements of the
context node.
Similarly a location step of .. is short for
from-parent(node()). For example, ../title
is short for from-parent(node())/from-children(title) and
so will select the title children of the parent of the
context node.
| [9] | AbbreviatedAbsoluteLocationPath | ::= | '//' RelativeLocationPath | |
| [10] | AbbreviatedRelativeLocationPath | ::= | RelativeLocationPath '//' Step | |
| [11] | AbbreviatedStep | ::= | AbbreviatedNodeTestStep | |
| | '.' | ||||
| | '..' | ||||
| [12] | AbbreviatedNodeTestStep | ::= | '@'? NodeTest Predicate* |
A VariableReference evaluates to the value to which the variable name is bound in the set of variable bindings in the context.
Parentheses may be used for grouping.
| [13] | Expr | ::= | OrExpr | |
| [14] | PrimaryExpr | ::= | VariableReference | |
| | '(' Expr ')' | ||||
| | Literal | ||||
| | Number | ||||
| | FunctionCall | ||||
| [15] | FunctionCall | ::= | NodeSetFunctionCall | |
| | BooleanFunctionCall | ||||
| | StringFunctionCall | ||||
| | NumberFunctionCall | ||||
| | SystemFunctionCall | ||||
| | ExtensionFunctionCall |
A location path can be used as an expression. The expression returns the set of nodes selected by the path.
The | operator computes the union of its operands
which must be node-sets.
Square brackets are used to filter expressions in the same way that they are used in location paths. It is an error if the expression to be filtered does not evaluate to a node-set. The context node list used for evaluating the expression in square brackets is the node-set to be filtered listed in document order.
The / operator and // operators combine
an arbitrary expression and a relative location path. It is an error
if the expression does not evaluate to a node-set. The /
operator does composition in the same way as when / is
used in a location path. As in location paths, // is
short for /from-descendants-or-self(node())/.
There are no types of objects that can be converted to node-sets. It is an error if evaluating a NodeSetExpr yields an object that is not a node-set.
The last() function returns the number of nodes in
the context node list. The position() function returns
the position of the context node in the context node list. The first
position is 1, and so the last position will be equal to
last().
The count() function returns the number of nodes in the
argument node-set.
The id() and idref() functions select
elements by their unique ID (see [4.2.1 Unique IDs]).
id() converts its argument to a string and returns a
node-set containing the element in the same document as the context
node with unique ID equal to that string, if there is such an element,
and otherwise returns an empty node-set. idref()
requires that its argument be a node-set; for each node in the
node-set, the value is split into a whitespace-separated list of
tokens; idref() returns a node-set containing the
elements in the same document as the context node that have a unique
ID equal to any of the tokens in the value of any of the nodes in the
node-set. For example,
id("foo") selects the element with unique ID
foo
id("foo")/from-children(para[position()=5]) selects
the fifth para child of the element with unique ID
foo
Ed. Note: No way to get an ID in another document. Can workaround with xsl:for-each. Maybe add optional second argument which gives document.
Issue (id-inverse): Should there be a way to get back from an element to the elements that reference it (eg by IDREF attributes)?
The key() and keyref() functions select a
set of nodes using the node key function in the expression evaluation
context. Both functions have a string as the first argument that
specifies the name of the key and have an expression as the second
argument. key() has a second argument that is a string
and returns a node-set containing the nodes in the same document as
the context node that have a value for the named key equal to this
string. keyref() has a second argument that is a node-set
and returns a node-set containing the nodes in the same document as
the context node that have a value for the named key equal to the
value of any of the nodes in the argument node-set. See [6.4.1 Declaring Keys] for how to declare a key.
The doc() and docref() functions allow
access to XML documents other than the initial source document. They
both rely on the ability to treat a string as a URI reference that is
mapped to a node-set; this mapping always takes places relative to a
node that can be used to resolve a relative URI into an absolute URI.
If the URI reference does not contain a fragment identifier, then it
will be mapped to a node-set containing the root node in a tree
representing the XML document whose document entity is the resource
identified by the URI. If the URI reference contains a fragment
identifier, then it will first map the URI to a tree representing the
XML document whose document entity is the resource identified by the
URI and then use the fragment identifier to select a set of nodes in
that tree; the semantics of the fragment identifier is dependant on
media type of the result of retrieving the URI. doc()
takes a string argument which it treats as a URI reference which is
mapped to a node-set relative to the element in the stylesheet
containing the expression. Note that a zero-length URI reference is a
reference to the document relative to which the URI reference is being
resolved; thus doc("") refers to the root node of the
stylesheet; the tree representation of the stylesheet is exactly the
same as if the XML document containing the stylesheet was the initial
source document. docref() takes a node-set argument; for
each node in the node-set, docref() treats the value of
the node as a URI reference that is mapped to a node-set relative to
that same node; docref() returns the union of the
resulting node-sets.
Ed. Note: What if the fragment identifier identifies something that isn't a set of nodes (eg a span or a substring within a text node)? What are the allowed media types for the returned data? What is document order for node sets including nodes from multiple documents?
The local-part() function returns a string containing
the local part of the name of the first node in the argument
node-set. If the node-set is empty or the first node has no name, an
empty string is returned. If the argument is omitted it defaults to
the context node.
The namespace() function returns a string containing
namespace of the name of the first node in the argument node-set. If
the node-set is empty or the first node has no name or the name has no
namespace, an empty string is returned. If the argument is omitted it
defaults to the context node.
The qname() function returns a string containing a
QName representing the name of
the first node in the argument. The QName must represent the name with
respect to the namespace declarations in effect on the node whose name
is being represented. Typically this will be the form in which the
name occurred in the XML source. This need not be the case if there
are namespace declarations in effect on the node that associate
multiple prefixes with the same namespace. However, an implementation
may include information about the original prefix in its
representation of nodes; in this case an implementation can ensure
that the returned string is always the same as the QName used in the XML source. If the
argument it omitted it defaults to the context node.
The generate-id() function returns a string that can
be used as a unique identifier for the first node in the argument
node-set. The unique identifier must consist of ASCII alphanumeric
characters and must start with an alphabetic character. An
implementation is free to generate an identifier in any convenient way
provided that it always generates the same identifier for the same
node and that different identifiers are always generated from
different nodes. An implementation is under no obligation to generate
the same identifiers each time a a document is transformed. If the
argument node-set is empty, the empty string is returned. If the
argument is omitted, it defaults to the context node.
| [16] | NodeSetExpr | ::= | Expr | |
| [17] | UnionExpr | ::= | PathExpr | |
| | UnionExpr '|' PathExpr | ||||
| [18] | PathExpr | ::= | LocationPath | |
| | FilterExpr | ||||
| | FilterExpr '/' RelativeLocationPath | ||||
| | FilterExpr '//' RelativeLocationPath | ||||
| [19] | FilterExpr | ::= | PrimaryExpr | |
| | FilterExpr Predicate | ||||
| [20] | NodeSetFunctionCall | ::= | 'last' '(' ')' | |
| | 'position' '(' ')' | ||||
| | 'count' '(' NodeSetExpr ')' | ||||
| | 'id' '(' StringExpr ')' | ||||
| | 'idref' '(' NodeSetExpr ')' | ||||
| | 'key' '(' StringExpr ',' StringExpr ')' | ||||
| | 'keyref' '(' StringExpr ',' NodeSetExpr ')' | ||||
| | 'doc' '(' StringExpr ')' | ||||
| | 'docref' '(' NodeSetExpr ')' | ||||
| | 'local-part' '(' NodeSetExpr? ')' | ||||
| | 'namespace' '(' NodeSetExpr? ')' | ||||
| | 'qname' '(' NodeSetExpr? ')' | ||||
| | 'generate-id' '(' NodeSetExpr? ')' |
An object of type boolean can have two values, true and false.
The boolean() function converts its argument to a
boolean as follows:
a number is true if and only if it is neither positive or negative zero nor NaN
a node-list is true if and only if it is non-empty
a result fragment is true if and only if it is non-empty
a string is true if and only if its length is non-zero
If the argument is omitted, it defaults to the context node.
A BooleanExpr is evaluated by
converting the result of evaluating the Expr to
a boolean as if by a call to the boolean() function.
An = expression is evaluated as follows. If at least
one operand is a boolean, then each operand is converted to a boolean
as if by applying the boolean() function and the operands
are compared as booleans. Otherwise, if at least one operand is a
number, then each operand is converted to a number as if by applying
the number() function and the operands are compared as
numbers; positive and negative zero compare equal. Otherwise both
operands are converted to strings as if by applying the
string() function and the operands are compared as
strings; two strings are equal if they contain the same sequence of
UCS characters.
A <, >, <= or
>= expression is evaluated by first converting each
operand to a number as if by a call to the number()
function and then comparing the two numbers.
Issue (node-set-comparision): What should the semantics of comparison operators be when either or both of the operands are node-sets? Should there be an "any" or "all" semantic?
An or expression is evaluated by evaluating each
operand and converting its value to a boolean. The result is true if
either value is true and false otherwise.
An and expression is evaluated by evaluating each
operand and converting its value to a boolean. The result is true if
both values are true and false otherwise.
The not() function returns true if its argument is
false, and false otherwise.
The true() function returns true.
The false() function returns false.
The lang() function returns true or false depending on
whether the language of the context node as specified by
xml:lang attributes is the same as or is a sublanguage of
the language specified by the argument string. The language of the
context node is determined by the value of the xml:lang
attribute on the context node, or, if the context node has no
xml:lang attribute, by the value of the
xml:lang attribute on the nearest ancestor of the context
node that has an xml:lang attribute. If there is no such
attribute, then lang() returns false. If there is such an
attribute, then lang() returns true if the attribute
value is equal to the argument ignoring case, or if there is some
suffix starting with - such that the attribute value is
equal to the argument ignoring that suffix of the attribute value and
ignoring case. For example, lang("en") would return true
if the context node is any of these five elements:
<para xml:lang="en"/> <div xml:lang="en"><para/></div> <para xml:lang="EN"/> <para xml:lang="en-us"/>
| [21] | BooleanExpr | ::= | Expr | |
| [22] | OrExpr | ::= | AndExpr | |
| | OrExpr 'or' AndExpr | ||||
| [23] | AndExpr | ::= | EqualityExpr | |
| | AndExpr 'and' EqualityExpr | ||||
| [24] | EqualityExpr | ::= | RelationalExpr | |
| | EqualityExpr '=' RelationalExpr | ||||
| [25] | RelationalExpr | ::= | AdditiveExpr | |
| | RelationalExpr '<' AdditiveExpr | ||||
| | RelationalExpr '>' AdditiveExpr | ||||
| | RelationalExpr '<=' AdditiveExpr | ||||
| | RelationalExpr '>=' AdditiveExpr | ||||
| [26] | BooleanFunctionCall | ::= | 'not' '(' BooleanExpr ')' | |
| | 'true' '(' ')' | ||||
| | 'false' '(' ')' | ||||
| | 'boolean' '(' Expr? ')' | ||||
| | 'lang' '(' StringExpr ')' |
A number represents a floating point number. A number can have any double-precision 64-bit format IEEE 754 value. These include a special "Not-a-Number" (NaN) value, positive and negative infinity, and positive and negative zero.
A NumberExpr is evaluated by
converting the result of evaluating the Expr to
a number as if by a call to the number() function.
The number() function converts its argument to a
number as follows:
if a string parses as Number possibly preceded or followed by whitespace, then it is converted to that number; otherwise it is converted to the number 0
Ed. Note: Would NaN be better than 0 here?
boolean true is converted to 1; boolean false is converted to 0
a node-set is first converted to a string as if by a call to the
string() function and then converted in the same way as a
string argument
Ed. Note: Should we take advantage of xml:lang here?
a result tree fragment is first converted to a string as if
by a call to the string() function and then converted in
the same way as a string argument
If the argument is omitted, it defaults to the context node.
The div operator performs floating point division
according to IEEE 754.
The quo operator performs a floating point division
and then truncates the result to an integer. For example,
5 quo 2 returns 2
5 quo -2 returns -2
-5 quo 2 returns -2
-5 quo -2 returns 2
The mod operator returns the remainder from the
quo operation. For example,
5 mod 2 returns 1
5 mod -2 returns 1
-5 mod 2 returns -1
-5 mod -2 returns -1
NOTE: This is the same as the % operator in Java and
ECMAScript.
NOTE: This is not the same as the IEEE remainder operation which returns the remainder from a rounding division.
The sum() function returns the sum of the values of
the nodes in the argument node-set.
The floor() function returns the largest (closest to
positive infinity) number that is not greater than the argument and
that is an integer.
The ceiling() function returns the smallest (closest
to negative infinity) number that is not less than the argument and
that is an integer.
The round() function returns the number that is
closest to the argument and that is an integer. If there are two such
numbers, then the one that is even is returned.
| [27] | AdditiveExpr | ::= | MultiplicativeExpr | |
| | AdditiveExpr '+' MultiplicativeExpr | ||||
| | AdditiveExpr '-' MultiplicativeExpr | ||||
| [28] | MultiplicativeExpr | ::= | UnaryExpr | |
| | MultiplicativeExpr MultiplyOperator UnaryExpr | ||||
| | MultiplicativeExpr 'div' UnaryExpr | ||||
| | MultiplicativeExpr 'mod' UnaryExpr | ||||
| | MultiplicativeExpr 'quo' UnaryExpr | ||||
| [29] | UnaryExpr | ::= | UnionExpr | |
| | '-' UnaryExpr | ||||
| [30] | NumberExpr | ::= | Expr | |
| [31] | NumberFunctionCall | ::= | 'number' '(' Expr? ')' | |
| | 'floor' '(' NumberExpr ')' | ||||
| | 'ceiling' '(' NumberExpr ')' | ||||
| | 'round' '(' NumberExpr ')' | ||||
| | 'sum' '(' NodeSetExpr ')' |
A string consists of a sequence of UCS characters.
A StringExpr is evaluated by
converting the result of evaluating the Expr to
a string as if by a call to the string() function.
The string() function converts an object to a string
as follows:
A node-set is converted to a string by returning the value of the node in the node-set that is first in document order. If the node-set is empty, an empty string is returned.
A result tree fragment is converted to a string by treating it as a single document fragment node that contains the nodes of the fragment, and then converting that document fragment node to a string in the same was as if the document fragment node were a source tree node.
A number is converted to a string by returning a string in
the form of a Number, preceded by a
- character if the number is negative.
Ed. Note: What about positive zero, negative zero, NaN and infinities?
The boolean false value is converted to the string
false. The boolean true value is converted to the
string true.
If the argument is omitted, it defaults to the context node.
The concat() function returns the concatenation of its
arguments.
The starts-with() function returns true if the first
argument string starts with the second argument string, and
otherwise returns false.
The contains() function returns true if the first
argument string contains the second argument string, and otherwise
returns false.
The substring-before() function returns the substring
of the first argument string that precedes the first occurrence of the
second argument string in the first argument string, or the empty
string if the first argument string does not contain the second
argument string. For example,
substring-before("1999/04/01","/") returns
1999.
The substring-after() function returns the substring
of the first argument string that follows the first occurrence of the
second argument string in the first argument string, or the empty
string if the first argument string does not contain the second
argument string. For example,
substring-after("1999/04/01","/") returns
04/01.
Ed. Note: Should the first argument of the above functions default to the value of the current node?
The normalize() function returns the argument string
with white space normalized by stripping leading and trailing
whitespace and replacing sequences of whitespace characters by a
single space. Whitespace characters are the same allowed by the S production in XML. If the argument is
omitted, it defaults to the context node converted to a string, in
other words the value of the context node.
The translate() function returns the first argument
string with occurrences of characters in the second argument string
replaced by the corresponding characters from the third argument
string. For example, translate("bar","abc","ABC") returns
the string BAr.
The format-number() function converts its first
argument to a string using the format pattern string specified by the
second argument and the locale named by the third argument, or the
default locale, if there is no third argument. The format pattern
string is in the syntax specified by the JDK 1.1 DecimalFormat class. The format pattern string is in a
localized notation: the locale determines what characters have a
special meaning in the pattern (with the exception of the quote
character, which is not localized). The format pattern must not
contain the currency sign (#x00A4); support for this feature was added
after the initial release of JDK 1.1. See [6.4.3 Declaring Locales]
for how to declare a locale.
| [32] | StringExpr | ::= | Expr | |
| [33] | StringFunction | ::= | 'string' '(' Expr? ')' | |
| | 'starts-with' '(' StringExpr ',' StringExpr ')' | ||||
| | 'contains' '(' StringExpr ',' StringExpr ')' | ||||
| | 'substring-before '(' StringExpr ',' StringExpr ')' | ||||
| | 'substring-after '(' StringExpr ',' StringExpr ')' | ||||
| | 'normalize' '(' StringExpr? ')' | ||||
| | 'translate' '(' StringExpr ',' StringExpr ',' StringExpr ')' | ||||
| | 'concat' '(' StringExpr (',' StringExpr)+ ')' | ||||
| | 'format-number' '(' NumberExpr ',' StringExpr (',' StringExpr)? ')' |
Issue (regex): Should XSLT support regular expressions for matching against any or all of pcdata content, attribute values, attribute names, element type names?
Issue (equality-case): Do we need to be able to do comparisons in a case insensitive way?
Issue (equality-normalize): Do we need to normalize strings before comparison? Does the stylesheet need to specify what kinds of normalization are required (eg compatibility character normalization)?
Issue (resolve-expr): Do we need a
resolve(NodeSetExpr)string expression that treats the characters as a relative URI and turns it into an absolute URI using the base URI of the addressed node?
Ed. Note: Add explanation of what a result tree fragment is.
The only operations that can be performed on a result tree fragment
are to convert it to a string or a boolean. In particular, it is not
permitted to use the /, //, and
[] on result tree fragments.
Expressions can only return values of type result tree fragment by referencing variables of type result tree fragment or calling extension functions that return a result tree fragment.
| [34] | ExtensionFunctionCall | ::= | CName '(' ( Expr ( ',' Expr)*)? ')' |
The CName is expanded to a name using the
namespace declarations from the evaluation context. The XSLT
processor attempts to locate an implementation of the extension
function with the specified name that it can use. The implementation
may be provided by an xsl:functions element (see [6.4.2 Declaring Extension Functions]) or the XSLT processor may be able to locate an
implementation by other means not specified by XSLT. If the XSLT
processor cannot locate such a function, then evaluating the
expression is an error. Otherwise the implementation is called
passing it the values of the expressions and the value returned by the
function is the value of the expression. The
function-available() function can be used to test whether
an implementation of a particular function is available (see [6.2.8 System Functions]). A XSLT processor is allowed always to give an error
when evaluating an ExtensionFunctionCall (with such
an XSLT processor the function-available() function would
always return false). Therefore if an XSLT stylesheet includes an ExtensionFunctionCall and does not
use the function-available() function to test for and
handle the possibility that an implementation of the function is not
available, then it may not be portable across all XSLT
implementations.
| [35] | SystemFunctionCall | ::= | 'system-property' '(' StringExpr ')' | |
| | 'function-available' '(' StringExpr ')' |
For both these functions, the StringExpr must evaluate to a string that is a QName. The QName is expanded into a name using the namespace declarations in scope for the expression.
The system-property() function returns an object
representing the value of the system property identified by the name.
If the name has no namespace, then the system-property()
function must return the string value of the operating system
environment variable whose name is equal to the local part of the
name. If there is no such system property, the empty string should be
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 processorThe function-available() function returns true if an
implementation of the named extension function is available. For
example:
<xsl:if test="function-available('jjc:currentDate')">
<xsl:value-of select="jjc:currentDate()"/>
</xsl:if>
When tokenizing, the longest possible token is always returned.
For readability, whitespace may be used in patterns even though not explicitly allowed by the grammar: ExprWhitespace may be freely added within patterns before or after any ExprToken.
A NodeType, FunctionName, CName
or AxisIdentifier token is recognized
only when the following token is (. An OperatorName token or MultiplyOperator token is recognized as
such only when there is a preceding token and the preceding token is
not one of @, (, [,
, or an Operator.
| [36] | ExprToken | ::= | '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | |
| | WildcardName | ||||
| | NodeType | ||||
| | Operator | ||||
| | FunctionName | ||||
| | AxisIdentifier | ||||
| | Literal | ||||
| | Number | ||||
| | CName | ||||
| | VariableReference | ||||
| [37] | Literal | ::= | '"' [^"]* '"' | |
| | "'" [^']* "'" | ||||
| [38] | Number | ::= | [0-9]+ ('.' [0-9]+)? | |
| | '.' [0-9]+ | ||||
| [39] | Operator | ::= | OperatorName | |
| | MultiplyOperator | ||||
| | '/' | '//' | '|' | '+' | '-' | '=' | '<'| '<=' | '>' | '>=' | ||||
| [40] | OperatorName | ::= | 'and' | 'or' | 'mod' | 'div' | 'quo' | |
| [41] | MultiplyOperator | ::= | '*' | |
| [42] | FunctionName | ::= | 'boolean' | |
| | 'ceiling' | ||||
| | 'concat' | ||||
| | 'contains' | ||||
| | 'count' | ||||
| | 'doc' | ||||
| | 'docref' | ||||
| | 'false' | ||||
| | 'floor' | ||||
| | 'format-number' | ||||
| | 'function-available' | ||||
| | 'generate-id' | ||||
| | 'id' | ||||
| | 'idref' | ||||
| | 'key' | ||||
| | 'keyref' | ||||
| | 'lang' | ||||
| | 'last' | ||||
| | 'local-part' | ||||
| | 'namespace' | ||||
| | 'normalize' | ||||
| | 'not' | ||||
| | 'number' | ||||
| | 'position' | ||||
| | 'qname' | ||||
| | 'round' | ||||
| | 'starts-with' | ||||
| | 'string' | ||||
| | 'substring-after' | ||||
| | 'substring-before' | ||||
| | 'sum' | ||||
| | 'system-property' | ||||
| | 'translate' | ||||
| | 'true' | ||||
| [43] | CName | ::= | NCName ':' NCName | |
| [44] | VariableReference | ::= | '$' NCName | |
| [45] | WildcardName | ::= | '*' | |
| | NCName ':' '*' | ||||
| | QName | ||||
| [46] | NodeType | ::= | 'comment' | |
| | 'text' | ||||
| | 'pi' | ||||
| | 'node' | ||||
| [47] | ExprWhitespace | ::= | S |
This section explains what expressions are allowed as patterns and what the semantics of matching a pattern are.
Here are some examples of patterns:
para matches any para element
* matches any element
chapter|appendix matches any
chapter element and any appendix
element
olist/item matches any item element with
an olist parent
appendix//para matches any para element with
an appendix ancestor element
/ matches the root node
text() matches any text node
pi() matches any processing instruction
id("W11") matches the element with unique ID
W11
para[1] matches any para element
that is the first para child element of its
parent
*[position()=1 and from-self(para)] matches any
para element that is the first child element of its
parent
para[last()=1] matches any para
element that is the only child element of its parent
items/item[position()>1] matches any
item element that has a items parent and
that is not the first item child of its parent
item[position() mod 2 = 1] would be true for any
item element that is an odd-numbered item
child of its parent.
div[@class="appendix"]//p matches any
p element with a div ancestor element that
has a class attribute with value
appendix
@class matches any class attribute
(not any element that has a class
attribute)
@* matches any attribute
A pattern must match the grammar for Pattern. A Pattern is
set of location path patterns separated by |. A location
path pattern is a location path none of the steps of which use either
AxisIdentifiers or . or
... Location path patterns can also start with an
id() or key() function call with a literal
argument (see [6.2.2 Node-sets]). Predicates in a pattern
can use arbitrary expressions just like predicates in a location
path.
| [48] | Pattern | ::= | LocationPathPattern | |
| | Pattern '|' LocationPathPattern | ||||
| [49] | LocationPathPattern | ::= | '/' RelativePathPattern? | |
| | IdKeyPattern (('/' | '//') RelativePathPattern)? | ||||
| | '//'? RelativePathPattern | ||||
| [50] | IdKeyPattern | ::= | 'id' '(' Literal ')' | |
| | 'key' '(' Literal ',' Literal ')' | ||||
| [51] | RelativePathPattern | ::= | StepPattern | |
| | RelativePathPattern '/' StepPattern | ||||
| | RelativePathPattern '//' StepPattern | ||||
| [52] | StepPattern | ::= | AbbreviatedNodeTestStep |
A pattern is defined to match a node if and only if there is possible context such that when the pattern is evaluated as an expression with that context, the node is a member of the resulting node-set. When a node is being matched the possible contexts have a context node that is the node being matched or any ancestor of that node, and a context node list containing just the context node.
For example, p matches any p element,
because for any p if the expression p is
evaluated with the parent of the p element as context the
resulting node-set will contain that p element as one of
its members.
NOTE: This matches even a p element that is the
document element, since the document root is the parent of the
document element.
Although the semantics of patterns are specified indirectly in
terms of expression evaluation, it is easy to understand the meaning
of a pattern directly without thinking in terms of expression
evaluation. In a pattern, | indicates alternatives; a
pattern with one or more | separated alternatives matches
if any one of the alternative matches. A pattern that consists of a
sequence of StepPatterns separated by
/ or // is matched from right to left. The
pattern only matches if the rightmost StepPattern matches and a suitable element
matches the rest of the pattern; if the separator is /
then only the parent is a suitable element; if the separator is
//, then any ancestor is a suitable element. A StepPattern that's a NodeTest matches if the NodeTest is true for the node and the node is
not an attribute node. A StepPattern
that starts with @ matches if the node is an attribute
node and the WildcardName matches the
name of the attribute. When [] is present, then the
first PredicateExpr in a StepPattern is evaluated with the element
being matched as the context node and the siblings of the elements
that match the NodeTest as the context node
list, unless the node being matched is an attribute node, in which
case the context node list is all the attributes that have the same
parent as the attribute being matched and that match the WildcardName.
For example
appendix//ulist/item[position()=1]
matches a node if and only if all of the following are true:
the NodeTest item is
true for the node and the node is not an attribute; in other words the
node is an item element
evaluating the PredicateExpr
position()=1 with the node as context node and the
siblings of the node that are item elements as the
context node list yields true
the node has a parent that matches
appendix//ulist; this will be true if the parent is a
ulist element that has an appendix ancestor
element.
Ed. Note: Need to revise above paragraph if we decide not to call the element to which an attribute is attached the parent of the attribute.
The xsl:key element is used to declare keys. The
name specifies the name of the key. The
match attribute is a Pattern; a
xsl:key element gives information about the keys of any
node that match the pattern specified in the match attribute. The
use attribute is a NodeSetExpr, which specifies the set of
values for which the node has a key of the specified name. A node
x has a key with name y and value
z if and only if there is a xsl:key element
such that:
x matches the pattern specified in the
match attribute of the xsl:key element;
the value of the name attribute of the
xsl:key element is equal to y;
and
z is the value of one or more of the nodes in
the node-set that results from evaluating the NodeSetExpr specified in the
use attribute of the xsl:key element with
x as the current node and with a node list containing
just x as the current node list.
Note that the NodeSetExpr may return
a node-set with more than one node; all of the returned nodes serve as
a key value. Note also that there may be more than one
xsl:key element that matches a given node; all of the
matching xsl:key elements are used.
Ed. Note: Add some examples.
Implementations of the extension functions in a namespace can be
provided using the xsl:functions element. The required
ns attribute specifies the namespace for which an
implementation is being provided. The value of the ns
attribute is a namespace prefix which is expanded to a namespace URI
using the namespace declarations in effect on the
xsl:functions element.
The implementation may be provided in two ways. If the
code attribute is present, then its value is a URI that
identifies a resource containing an implementation of the functions in
the namespace; in this case a type attribute giving the
MIME media type of the data providing the implementation may also be
provided, so as to allow the XSLT processor to avoid fetching
resources of types that it is unable to make use of. If the
code attribute is not present, then the content of the
xsl:functions element contains the implementation of the
functions; in this case the type attribute
must be present.
Multiple alternative implementations may be provided for the same namespace. For example,
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
xmlns:jjc="http://www.jclark.com">
<xsl:template match="/">
<xsl:value-of select="jjc:currentDate()"/>
</xsl:template>
<xsl:functions ns="jjc" type="text/javascript">
function currentDate() {
return Date().toString()
}
<p>When multiple alternative implementations are provided, it is up to
the XSLT processor to determine which to use.</p>
</xsl:functions>
<xsl:functions ns="jjc" code="clsid:9A447990-E64D-11D2-8C29-00A0CC2428DA"/>
</xsl:stylesheet>
The xsl:functions element may also have an
archive attribute that specifies a whitespace-separated
list of URIs of resources relevant to the provided implementation.
An XSLT processor is not required to be able to make use of
implementations provided by xsl:functions elements. The
MIME media types that an XSLT processor is able to make use of and the
way the XSLT processor interfaces with implementations is dependent on
the particular XSLT processor. Therefore if an XSLT stylesheet
includes an ExtensionFunctionCall of an
extension function in a namespace for which an implementation is
provided by an xsl:functions element, then it may not be
portable across all XSLT implementations.
The xsl:locale element declares a locale which
controls the interpretation of a format pattern used by the
format-number() function. If there is a
name attribute then the element declares a named locale,
otherwise it declares the default locale.
The other attributes on xsl:locale correspond to the
methods on the JDK 1.1 DecimalFormatSymbols class. For each
get/set method pair there is an attribute
defined for the xsl:locale element. The default values
are given in the XSLT DTD (see [A DTD Fragment for XSLT Stylesheets]).
The following attributes specify characters that may appear in the result of formatting the number and also control the interpretation of characters in the format pattern:
decimal-separator specifies the character used
for the decimal sign
grouping-separator specifies the character used
as a grouping (eg thousands) separator
percent specifies the character used as a
percent sign
per-mill specifies the character used as a per
mille sign
zero-digit specifies the character used as the
digit zero
The followi