Extensible Stylesheet Language (XSL)
Version 1.0
WD-xsl-
World Wide Web Consortium Working Draft
http://www.w3.org/TR/ /WD-xsl-
http://www.w3.org/TR/ /WD-xsl- .xml
http://www.w3.org/TR/ /WD-xsl- .html
http://www.w3.org/TR/ /WD-xsl- .pdf
http://www.w3.org/TR/WD-xsl
http://www.w3.org/TR/1998/WD-xsl-19980818
James Clark
jjc@jclark.com
Stephen Deach
Adobe
sdeach@adobe.com
This is a W3C Working Draft for review by W3C members and other interested parties. This adds additional functionality to what was described in the the previous draft, however the basic of the previous draft remains unchanged. It is a draft document and may be updated, replaced, or obsoleted by other documents at any time. 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.
Comments may be sent to xsl-editors@w3.org. Public discussion of XSL takes place on the XSL-List mailing list.
XSL is a language for expressing stylesheets. It consists of two parts:
1. a language for transforming XML documents, and
2. an XML vocabulary for specifying formatting semantics.
An XSL stylesheet specifies the presentation of a class of XML documents by describing how an instance of the class is transformed into an XML document that uses the formatting vocabulary.
English
EBNF
See RCS log for revision history.

Overview
XSL is a language for expressing stylesheets. Each stylesheet describes rules for presenting a class of XML source documents. There are two parts to the presentation process. First, the result tree is constructed from the source tree. Second, the result tree is interpreted to produce formatted output on a display, on paper, in speech or onto other media.
The first part, constructing the result tree, 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, the source tree can be filtered and reordered, and arbitrary structure can be added.
The second part, formatting, is achieved by using the formatting vocabulary specified in this document to construct the result tree. Formally, this vocabulary is an XML namespace. Each element type in the vocabulary corresponds to a formatting object class. A formatting object class represents a particular kind of formatting behavior. For example, the block formatting object class represents the breaking of the content of a paragraph into lines. Each attribute in the vocabulary corresponds to a formatting property. A formatting object class has a specific set of formatting properties which provide finer control over the behavior of the formatting object class; for example, controlling indenting of lines, spacing between lines, and spacing before and after the collection of lines. A formatting object can have content, and its formatting behavior is applied to its content.
XSL does not require result trees to use the formatting vocabulary and thus can be used for general XML transformations. For example, XSL can be used to transform XML to well-formed HTML, that is, XML that uses the element types and attributes defined by HTML.
When the result tree uses the formatting vocabulary, a conforming XSL implementation must be able to interpret the result tree according to the semantics of the formatting vocabulary as defined in this document; it may also be able to externalize the result tree as XML, but it is not required to be able to do so.
This document does not specify how a stylesheet is associated with an XML document. It is recommended that XSL processors support the mechanism described in .

Tree Construction

Overview
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 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 .
XSL uses XML namespaces to distinguish elements that are instructions to the XSL processor from elements that specify literal result tree structure. Instruction elements all belong to the XSL namespace. The examples in this document use a prefix of xsl: for elements in the XSL namespace.
An XSL stylesheet contains an xsl:stylesheet document element. This element may contain xsl:template elements specifying template rules, which will be described later in this document.
The following is an example of a simple XSL stylesheet that constructs a result tree for a sequence of para elements. The result-ns="fo" attribute indicates that a tree using the formatting object vocabulary is being constructed. The rule for the root node specifies the use of a page sequence formatted with any font with serifs. The para elements become block formatting objects which are set in 10 point type with a 12 point space before each block.
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/TR/WD-xsl"
  xmlns:fo="http://www.w3.org/TR/WD-xsl/FO"
  result-ns="fo">
  <xsl:template match="/">
    <fo:page-sequence font-family="serif">
       <xsl:apply-templates/>
    </fo:page-sequence>
  </xsl:template>

  <xsl:template match="para">
    <fo:block font-size="10pt" space-before="12pt">
      <xsl:apply-templates/>
    </fo:block>
  </xsl:template>
</xsl:stylesheet>
The xsl:stylesheet element can also contain elements importing other XSL stylesheets, elements defining macros, elements defining global constants, and elements identifying source attributes as individual element identifiers.

Stylesheet Structure
A stylesheet is represented by an xsl:stylesheet element in an XML document.
XSL processors must use the XML namespaces mechanism for both source documents and stylesheets. All XSL defined elements, that is those specified in this document with a prefix of xsl:, will only be recognized by the XSL processor if they belong to a namespace with the URI http://www.w3.org/TR/WD-xsl; XSL defined elements are recognized only in the stylesheet not in the source document.
Should there be some way for a stylesheet to indicate which version of XSL it conforms to? Can this be done through the URI of the XSL namespace?
The xsl:stylesheet element has an optional result-ns attribute; the value must be a namespace prefix. If this attribute is specified, all result elements must belong to the namespace identified by this prefix (the result namespace). 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. If the result-ns attribute specifies the XSL Formatting Objects namespace, then in addition to constructing the result XML tree, the XSL processor must interpret it according to the semantics defined in this document. The XSL Formatting Objects namespace has the URI http://www.w3.org/TR/WD-xsl/FO. The examples in this document use the fo: prefix for this namespace.
If an implementation wishes to use something in the result tree or stylesheet to control the output of a non-XML representation of the result tree, it should use the result namespace. In particular, if it wishes to make use of something in the result tree or stylesheet to indicate that the result tree should be output as HTML that conforms to the HTML 4.0 Recommendation rather than as XML, it should use a result namespace of http://www.w3.org/TR/REC-html40; for example,

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/TR/WD-xsl"
  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 may contain the following types of elements:
1. xsl:import
2. xsl:include
3. xsl:id
4. xsl:strip-space
5. xsl:preserve-space
6. xsl:macro
7. xsl:attribute-set
8. xsl:constant
9. 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/TR/WD-xsl">
  <xsl:import href="..."/>

  <xsl:include href="..."/>

  <xsl:id attribute="..."/>

  <xsl:strip-space element="..."/>

  <xsl:preserve-space element="..."/>

  <xsl:macro name="...">
   ...
  </xsl:macro>

  <xsl:attribute-set name="...">
  ...
  </xsl:attribute-set>

  <xsl:constant name="..." value="..."/>

  <xsl:template match="...">
    ...
  </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.
Should we provide the functionality of CSS's @media rule and if so how?

Processing Model
This needs expanding and polishing.
A node is processed to create a result tree fragment. The result tree is constructed by processing the root node. A node is processed by finding all the template rules with patterns that match the node, and choosing the best amongst them. The chosen rule's template is then instantiated for the node. During the instantiation of a template, the node for which the template is being instantiated is called the current node. A template typically contains instructions that select an additional sequence of source nodes for processing. A sequence of source nodes is processed by appending the result tree structure created by processing each of the members of the sequence in order. The process of matching, instantiation and selection is continued recursively until no new source nodes are selected for processing.
Implementations are free to process the source document in any way that produces the same result as if it were processed using this processing model.

Data Model
XSL 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 XSL. The XML document resulting from the tree construction process is also a tree. This section describes how XSL models an XML document as a tree. This model is conceptual only and does not mandate any particular implementation.
XML documents operated on by XSL must conform to the XML namespaces specification .
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 determing 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.
Should XSL provide support for external data entities and notations?

Root Node
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.

Element Nodes
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 (see ); the URI will be null if the element type name has no prefix and there is no default namespace in scope.
The children of an element node are the element nodes and characters 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 character children, the element node children, and the descendants of the element node children.
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.

Unique IDs
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. Since XSL must also work with XML documents that do not have a DTD, stylesheets may specify which attributes in the source document should be treated as IDs. The xsl:id element has a required attribute attribute, which gives the name of an attribute in the source document that should be treated as specifying the element's ID. A stylesheet may contain more than one xsl:id element, for cases where the source document uses several attributes as IDs. An xsl:id element also has an optional element attribute which specifies the name of an element type; when the element attribute is specified, then the xsl:id element specifies that the attribute attribute of element elements are treated as IDs. xsl:id elements may only occur in the stylesheet body (not within a rule). The following causes XSL to treat all name attributes in the source document as IDs.
<xsl:id attribute="name"/>
It is an error if, as a consequence of the use of xsl:id, there is more than one element with the same ID in the source tree. An XSL processor may signal the error; if it does not signal the error, it must recover by treating only the first (in document order) of the elements as having that ID.
Should it be possible for a unique id to be specified in the content of an element instead of in an attribute?

Base URI
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.

Attribute Nodes
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, 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 ); 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 . An attribute value whose value is of zero length is not treated specially.
There are no attribute nodes for attributes that declare namespaces (see ).
Should we specify something about how we expect XSL processors to process external DTDs and parameter entities? For example, what happens if an attribute default is declared in an external DTD?

Namespace Nodes
Each element has an associated set of namespace nodes, one for each namespace prefix that is in scope for 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.
An attribute xmlns="" undeclares the default namespace (see ).
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 XSL 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.
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.

Processing Instruction Nodes
There is a processing instruction node for every processing instruction.
What about processing instructions in the internal subset or elsewhere in the DTD?
An 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 ?>.

Comment Nodes
There is a comment node for every comment.
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 -->.

Text Nodes
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 &lt;. 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 .

Whitespace Stripping
After the tree has been constructed, but before it is otherwise processed by XSL, 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.
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 an element type to be removed from the set of whitespace-preserving element types. The element attribute gives the name of the element type.
- The xsl:preserve-space element causes an element type to be added to the set whitespace-preserving element types. The element attribute gives the name of the element type.
Should the value of the element attribute of xsl:strip-space, xsl:preserve-space and xsl:id be a list of element type names (and thus be renamed to elements)? If so, should the attribute attribute of xsl:id also be a list of attribute names?
Clarify how these declarations interact with each other and with xsl:import.
The xsl:stylesheet element can include an indent-result attribute with values yes or no. If the stylesheet specifies indent-result="yes", then the XSL 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 XSL 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.

Template Rules
A template rule is specified with the xsl:template element. The match attribute identifies the source node or nodes to which the rule applies. The content of the xsl:template element is the template.
For example, an XML document might contain:
This is an <emph>important</emph> point.
The following template rule matches elements of type emph and has a template which produces a fo:sequence formatting object with a font-weight property of bold.
<xsl:template match="emph">
  <fo:sequence font-weight="bold">
    <xsl:apply-templates/>
  </fo:sequence>
</xsl:template>

As described later, the xsl:apply-templates element recursively processes the children of the source element.

Conflict Resolution for Template Rules
It is possible for a source node to match more than one template rule. The template rule to be used is determined as follows:
1. First, all matching template rules that are less important than the most important matching template rule or rules are eliminated from consideration.
2. Next, all matching template rules that have a lower priority than the matching template rule or rules with the highest priority are eliminated from consideration. The priority of a rule is specified by the priority attribute on the rule. The value of this must be a real number (positive or negative). The default priority is 0.
Say exactly what syntax is allowed for real numbers.
It is an error if this leaves more than one matching template rule. An XSL processor may signal the error; if it does not signal the error, it must recover by choosing from amongst the matching template rules that are left the one that occurs last in the stylesheet.

Built-in Template Rule
There is a built-in template rule to allow recursive processing to continue in the absence of a successful pattern match by an explicit rule in the stylesheet. This rule applies to both element nodes and the root node. The following shows the equivalent of the built-in template rule:
<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>
The built-in template rule is treated as if it were imported implicitly before the stylesheet and so is considered less important than all other template rules. Thus the author can override the built-in rule by including an explicit rule with match="*|/".
There is also a built-in template rule for text nodes that copies text through:
<xsl:template match="text()">
  <xsl:value-of select="."/>
</xsl:template>
The built-in rule does not apply to processing instructions and comments. When a comment or processing instruction is processed, and no rule is matched, nothing is created.

Patterns

Introduction
This section introduces the syntax and semantics of XSL patterns. The formal, definitive specification is in the following section.
A pattern is a string which selects a set nodes in a source document. The selection is relative to the current node. The simplest pattern is an element type name; it selects all the child elements of the current node with that element type name. For example, the pattern chapter selects all the chapter child elements of the current node.
A pattern can also be matched against a node. If a node could be selected by a pattern, then the node is considered to match the pattern. More precisely, for any pattern and any document there is a matching set of nodes; this is the union, for each node in the document, of the set of nodes selected by the pattern with that node as the current node. For example, a pattern chapter matches any chapter element because if the current node was the parent of the chapter element, the chapter element would be one of the nodes selected by the pattern chapter. This includes the case where the chapter element is the document element, because the root node is the parent of the document element.
The | operator can be used to express alternatives. For example, the pattern emph|b matches both emph elements and b elements.
Patterns can be composed together with the / operator in a path-like manner. For example, a pattern chapter/section selects the chapter child elements of the current node, and then for each selected chapter element, selects the section children; in other words, it selects the section grandchildren of the current node that have chapter parents. A node would match a pattern chapter/section if it was a section element with a chapter parent.
/ binds more tightly than |. Thus the pattern ol/li|ul/li matches li elements that have a ol or ul parent.
Whitespace can be used around operators in patterns to improve readability. Thus ol/li|ul/li can be written as ol/li | ul/li.
* can be used instead of an element type name as a wildcard. For example, a pattern * would select all element children of the current node; a pattern */section would select all section grandchildren of the current node. A pattern chapter/* would match any element that has a chapter parent.
A // can be used instead of / to select from descendants instead of from children. For example, a pattern chapter//p selects all the p descendants of chapter children of the current node, and it matches all p elements that have a chapter ancestor.
A pattern . selects the current node. This is useful with //. For example, .//div selects all div descendant elements of the current node.
Similarily .. selects the parent of the current node. For example, ../item selects the item sibling elements of the current node.
Other types of node are treated in a similar way to elements.
- The attributes of an element are treated like the child elements; an attribute is distinguished from a child element by prefixing its name with @. For example, @date will select the date attribute of the current element; employee/@salary will select the salary attribute of each employee child element of the current node. A wildcard @* is allowed just as with elements; a pattern @* selects all attributes of the current node.
- A pattern comment() selects all comment children of the current node. Thus a pattern comment() will match any comment node.
- A pattern pi() selects all processing instruction children of the current node. An argument can be used to specify the target. Thus pi("xml-stylesheet") matches any processing instruction with a target xml-stylesheet. Note that the argument must be quoted.
The set of nodes selected by a pattern can be refined by following the pattern by a test in square brackets ([]). Each node in the set is tested. The result includes only those nodes for which test succeeds. The following are allowed as tests:
- A pattern can be used a test; the test succeeds if the pattern selects one or more nodes when the node being tested is the current node. For example, a pattern list[@type] matches a list element with a type attribute; a pattern book[editor] selects book children elements of the current node that have at least one editor child element.
- A pattern can be compared to string. For example, a pattern list[@type="ordered"] would match any list with an attribute type with value ordered; a pattern employee[location="USA"] would select employee children of the current element that have a location child with content equal to USA.
- The position of a node relative to its siblings can be tested.
  - first-of-any() succeeds if the node being tested is the first element child
  - last-of-any() succeeds if the node being tested is the last element child
  - first-of-type() succeeds if the node being tested is the first element child of its element type
  - last-of-type() succeeds if the node being tested is the first element child of its element type
- A test can be negated using not(). For example, list[not(@type)] matches any list element without a type attribute.
- Tests can be combined with and and or. For example,
back/div[first-of-type() and last-of-type()]
matches a div element with a back parent, when it is the only div child of its parent.
The [] operator binds more tightly than |. Thus the pattern ol|list[@type="ordered"] matches either list elements with a type attribute with value ordered or ol elements.
The root node is treated is specially. A / at the beginning of a pattern selects the root node (not the document element). For example, a pattern that is just / matches the root node; a pattern /div will match the document element it is a div element; a pattern /* will match the document element whatever is. When a pattern starts with / the current node is irrelevant.
A pattern can also start with //. //foo means the same as /.//foo: it selects the foo descendants of the root node, which implies that it selects all foo elements. When a pattern starts with // the current node is irrelevant.
The ancestor function allows selection of an ancestor of the current node. The argument is a match pattern. It selects the first ancestor of the current node that matches the argument. For example, ancestor(chapter)/title will select the title children of the first ancestor of the current node that is a chapter.
The id function allows ID references to be followed. The argument can be a literal string. For example, id('foo') will select the element with ID foo; if there is no such element, the empty node set will be returned. Multiple whitespace separated IDs are also allowed; this id('foo bar') would select elements with an ID foo or bar. The argument can be a pattern instead of a literal string; for each node selected by the pattern, the value of the node is treated as whitespace separated list of ID references. For example, if the current node is an element with an IDREF or IDREFS attribute named ref, then a pattern id(@ref) would select the elements referenced by the ref attribute.
Would it be less confusing to call this idref?

Syntax and Semantics
An expression is evaluated with respect to a context, which is a single node. The result of evaluating an expression is a set of nodes or a boolean.
In the following grammar, the nonterminal QName is defined in , and S is defined in .

Selecting
SelectExpr
UnionExpr
A select pattern must match the production for SelectExpr; it returns the list of nodes that results from evaluating the SelectExpr with the current node as context; the nodes are in the list are in document order.

Matching
MatchExpr
SelectExpr
A match pattern must match the production for MatchExpr; a node matches the match pattern if the MatchExpr returns true when evaluated with that node as context.
The result of the MatchExpr is true if, for any node in the document that contains the context of the MatchExpr, the result of evaluating the SelectExpr with that node as context contains the context of the MatchExpr. Otherwise the result is false.
For implementation reasons, the functionality of MatchExprs is restricted as follows:
- Within a BooleanExpr in a MatchExpr, a SelectExpr must be a SubNodeExpr. More informally, within [] in a match pattern, /, // and [] must not be used. For example, foo[bar/baz] is not allowed as a match pattern.
- Within a MatchExpr, an OtherNodeExpr must be a ConstantIdExpr.

Unions
UnionExpr
PathExpr
| (
PathExpr
'|'
UnionExpr
)
The context of the right hand side expressions is the context of the left hand side expression. The results of the right hand side expressions are node sets. The result of the left hand side UnionExpr is the union of the results of the right hand side expressions.

Paths
PathExpr
AbsolutePathExpr
| ComposeExpr
The context of the right hand side expressions is the context of the left hand side expression. The result of the left hand side is the result of the right hand side. The result is a node set.

Absolute Paths
AbsolutePathExpr
'/' SubtreeExpr?
If the SubtreeExpr is present, then the context for the SubtreeExpr is the root node, and the result is the result of the SubtreeExpr. Otherwise the result is the root node.

Subtrees
SubtreeExpr
'/'? ComposeExpr
If the / is present, then the result SubtreeExpr is the union, for each node in the subtree rooted at the context of the SubtreeExpr, of the result of evaluating the ComposeExpr with that node as context. Otherwise the SubtreeExpr is equivalent to ComposeExpr.

Composition
ComposeExpr
FilterExpr
| (
FilterExpr
'/'
SubtreeExpr
)
The context of the FilterExpr is the context of the ComposeExpr. If the SubtreeExpr is present, then, for each node in the result of the FilterExpr, the SubtreeExpr is evaluated with that node as the context; the result of the ComposeExpr is the union of the results of evaluating the SubtreeExpr. Otherwise the result is the result of the FilterExpr.

Filtering
FilterExpr
NodeExpr
( '['
BooleanExpr
']' )?
The context of the NodeExpr is the context of the FilterExpr. If the BooleanExpr is present, then for each node in the result of the NodeExpr, the BooleanExpr is evaluated with that node as context; the result consists of those nodes for which the BooleanExpr evaluates to true.

Selecting Nodes
NodeExpr
SubNodeExpr
| OtherNodeExpr
SubNodeExpr
ElementExpr
| AttributeExpr
| TextExpr
| CommentExpr
| PiExpr
OtherNodeExpr
IdExpr
| AncestorExpr
| IdentityExpr
| ParentExpr
The context of the right hand side expressions is the context of the left hand side expression. The results of the right hand side expressions are node sets. The result of the left hand side is the result of the left hand side expression.
Should it be possible for patterns to select nodes in documents other than the source document?
Should there be qualifiers that constrain an element to have an immediately preceding or following sibling of a particular type?

Elements
ElementExpr
QName
| '*'
If * is specified, then the result is the child elements of the context of the ElementExpr. Otherwise, the result is the set of all elements that are the children of the context of ElementExpr and whose name is equal to QName.
When comparing the name of an element to a QName, the QName is expanded into a local name and a possibly null URI. This expansion is done in the same way as for element type names in start and end-tags except that the 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 element type names are are compared (see ).
Should patterns of the form foo:* or *:foo be allowed? If so, should * match any element or any element without a namespace URI?

Attributes
AttributeExpr
('@' QName)
| ('@' '*')
If * is specified, the result is the set of attribute nodes of the context of the AttributeExpr. If a QName is specified, the result is the attribute node of the context of the AttributeExpr named QName, or the empty node set if there is no such attribute node. When matching attribute names, the expanded names are compared (see ). The QName is expanded in the same way as a QName in an ElementExpr.
Do we need to be able to match attributes in a case insensitive way?

Processing Instructions
PiExpr
'pi(' Literal? ')'
If the Literal is present, the result is the set of processing instruction nodes which are children of the context of the PiExpr and whose target is equal to the value of Literal. Otherwise the result is the set of processing instruction nodes which are children of the context of the PiExpr.

Text
TextExpr
'text(' ')'
The result is the set of all text nodes whose parent is a node in the context of the TextExpr.
Should XSL support regular expressions for matching against any or all of pcdata content, attribute values, attribute names, element type names?

Comments
CommentExpr
'comment(' ')'
The result is the set of all comment nodes which are children of the context of the CommentExpr.

IDs
IdExpr
ConstantIdExpr
| VariableIdExpr
ConstantIdExpr
'id(' Literal ')'
VariableIdExpr
'id(' SelectExpr ')'
The context of the SelectExpr is the context of the IdExpr. A set of names is computed from the argument as follows:
- If it is a ConstantIdExpr, then the value of the Literal is treated as a whitespace-separated list of names; the set of names are the members of the list.
- Otherwise, the value of each node in the result of the SelectExpr is treated as a whitespace-separated list of names; the set of names is the union for each node of the members of the list.
The result is the set of element nodes whose ID (see ) is one of the names in the set of names specified by the argument.
Should there be a way of specifying that an attribute serves as a class attribute and then pattern syntax that treats class attributes specially?

Ancestors
AncestorExpr
'ancestor(' MatchExpr ')'
The result the first ancestor of the context of the AncestorExpr such that MatchExpr, when evaluated with that ancestor as the context, has a result of true. If there is no such ancestor, the result is the empty node set.

Identity
IdentityExpr '.'
The result is the context of the IdentityExpr.

Parents
ParentExpr '..'
The result is the parent of the context of the ParentExpr. If the context is the root node, then the result is the empty node set.

Boolean Expressions
BooleanExpr
AndExpr
| OrExpr
| BooleanPrimaryExpr
BooleanPrimaryExpr
BooleanGroupExpr
| NotExpr
| PositionalExpr
| TestExpr
| EqualityExpr
The result of a BooleanExpr is true or false. The context of the right hand side expressions is the context of the BooleanExpr. The result of the BooleanExpr is the result of the right hand side.

And
AndExpr
BooleanPrimaryExpr ( 'and' BooleanPrimaryExpr )+
The context for each BooleanPrimaryExpr is the context of the AndExpr. The result is true if the result of all of the BooleanPrimaryExprs is true; otherwise the result is false.

Or
OrExpr
BooleanPrimaryExpr ( 'or' BooleanPrimaryExpr )+
The context for each BooleanPrimaryExpr is the context of the OrExpr. The result is true if the result of any of the BooleanPrimaryExprs is true; otherwise the result is false.

Grouping
BooleanGroupExpr
'(' BooleanExpr ')'
The result of the left hand side is the result of the right hand side. The context of the right hand side is the context of the left hand side.

Negation
NotExpr
'not(' BooleanExpr ')'
The result of the NotExpr is true if the result of the BooleanExpr is false; otherwise the result is false.

Position
PositionalExpr
'first-of-type(' ')'
| 'last-of-type(' ')'
| 'first-of-any(' ')'
| 'last-of-any(' ')'
The context of the PositionalExpr is a single node.
- For first-of-type(), the result is true if the context node is an element and the element has no preceding siblings that are elements with the same element type name, and false otherwise.
- For first-of-any(), the result is true if the context node is an element and the element has no preceding siblings that are elements, and false otherwise.
- For last-of-type(), the result is true if the context node is an element and the element has no following siblings that are elements with the same element type name, and false otherwise.
- For last-of-any(), the result is true if the context node is an element and the element has no following siblings that are elements, and false otherwise.

Testing Existence
TestExpr
SelectExpr
The context of the SelectExpr is the context of the EqualityExpr. The result of the TestExpr is true if the result of the SelectExpr is non-empty. Otherwise the result is false.

Equality
EqualityExpr
SelectExpr
'='
Literal
The context of the SelectExpr is the context of the EqualityExpr. The result is true if there is a node in the result of the SelectExpr whose value is equal to the value of the Literal.
We plan to use the data-typing facilities being developed by the XML Schema WG to allow ordered comparisons.

Literal
Literal '"' [^"]* '"' | "'" [^']* "'"
The value of the Literal is the sequence of characters inside the " or ' characters>.

Pattern Lexical Structure
PatternToken
'/' | '@' | '(' | ')' | '|' | '[' | ']' | ',' | '=' | '.' | '..' | '*'
| 'id(' | 'ancestor(' | 'comment(' | 'pi(' | 'text(' | 'not('
| 'first-of-type('
| 'last-of-type('
| 'first-of-any('
| 'last-of-any('
| QName
| Literal
PatternWhitespace
S
For readability, whitespace may be used in patterns even though not explicitly allowed by the grammar: PatternWhitespace may be freely added within patterns before or after any PatternToken.

Templates

Overview
When the rule that is to be applied to the source element has been identified, the rule's template is instantiated. A template can contain literal result elements, character data and instructions for creating fragments of the result tree. Instructions are represented by elements in the XSL namespace.
The xsl:apply-templates instruction can select descendant nodes for processing. Without any attribute, the xsl:apply-templates instruction processes the immediate children nodes of the source element; a select attribute can be used to process nodes selected by a specified pattern.
<xsl:template match="chapter/title">
  <fo:rule-graphic/>
  <fo:block space-before="2pt">
    <xsl:text>Chapter </xsl:text>
    <xsl:number/>
    <xsl:text>: </xsl:text>
    <xsl:apply-templates/>
  </fo:block>
  <fo:rule-graphic/>
</xsl:template>
Should there be an instruction that generates an error, like the error procedure in DSSSL?
Should it be possible to create multiple result trees?

Creating Elements and Attributes

Literal Result Elements
In a template an element in the stylesheet that does not belong to the XSL namespace is instantiated to create an element node of the same type. The created element node will have the attribute nodes that were present on the element node in the stylesheet tree. The created element node will also have the namespace nodes that were present on the element node in the stylesheet tree with the exception of any namespace node whose value is the XSL namespace URI (http://www.w3.org/TR/WD-xsl).
The value of an attribute of a literal result element is interpreted as an attribute value template: it can contain string expressions contained in curly braces ({}).
Namespace URIs that occur literally in the stylesheet and that are being used to create nodes in the result tree can be quoted. This applies to:
- the namespace URI in the expanded name of an literal result element in the stylesheet
- the namespace URI in the expanded name of an attribute specified on a literal result element in the stylesheet
- the value of a namespace node on a literal result element in the stylesheet
A namespace URI is quoted by prefixing it with the string quote:. This prefix will be removed when the template is instantiated to create the result element node with its associated attribute nodes and namespace nodes.
When literal result elements are being used to create element, attribute and namespace nodes which use the XSL namespace URI, the namespace must be quoted to avoid misinterpretation by the XSL processor.
It may be necessary also to quote other namespaces. For example, literal result elements belonging to a namespace dealing with digital signatures might cause XSL stylesheets to mishandled by general purpose security software; quoting the namespace would avoid the possibility of such mishandling.
For example, the stylesheet
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/TR/WD-xsl"
  xmlns:fo="http://www.w3.org/TR/WD-xsl/FO"
  xmlns:qxsl="quote:http://www.w3.org/TR/WD-xsl">

<xsl:template match="/">
  <qxsl:stylesheet>
    <xsl:apply-templates/>
  </qxsl:stylesheet>
</xsl:template>

<xsl:template match="block">
  <qxsl:template match="{.}">
     <fo:block><qxsl:apply-templates/></fo:block>
  </qxsl:template>
</xsl:template>

</xsl:stylesheet>
will generate an XSL stylesheet from a document of the form:
<elements>
<block>p</block>
<block>h1</block>
<block>h2</block>
<block>h3</block>
<block>h4</block>
</elements>

Named Attribute Sets
The xsl:attribute-set element defines a named set of attributes. The name attribute specifies the name of the attribute set. The content of the xsl:attribute-set element consists of xsl:attribute elements that specify attributes. A literal result element can specify an attribute set name as the value of the xsl:use attribute.
The following example creates a named attribute set title-style and uses it in a template rule.
<xsl:attribute-set name="title-style">
  <xsl:attribute name="font-size">12pt</xsl:attribute>
  <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>

<xsl:template match="chapter/heading">
  <fo:block xsl:use="title-style" quadding="start">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>
If the xsl:use attribute is specified on an element that also specifies a value for an attribute that is also part of the attribute set named by xsl:use, the attribute in the named attribute set is not used.
Multiple definitions of an attribute set with the same name are merged. An attribute from a definition that is more important takes precedence over an attribute from a definition that is less important. It is an error if there are two attribute sets with the same name that are equally important and that both contain the same attribute unless there is a more important definition of the attribute set that also contains the attribute. An XSL processor may signal the error; if it does not signal the error, it must recover by choosing from amongst the most important definitions that specify the attribute the one that was specified last in the stylesheet.
An xsl:use attribute may specify a list of attribute set names separated by whitespace. These attribute sets will be merged treating the list as being in order of increasing importance.

Creating Elements with xsl:element
The xsl:element allows an element to be created with a computed name. The xsl:element attribute has a required name attribute that specifies the name of the element. The name attribute is interpreted as an attribute value template. It is instantiated to create an element with the specified name. The content of the xsl:element element is a template for the attributes and children of the created element.
The value of the name attribute after instantiation must have one of two forms:
- It can be a QName. In this case the name is expanded in the same way as an element type name using the namespace declarations in scope for the xsl:element element in the stylesheet.
- It can be a namespace URI followed by a # character followed by an NCName. This can be used conjunction with a NameExpr to compute a qualified name.

Creating Attributes with xsl:attribute
The xsl:attribute element can be used to add attributes to result elements whether created by literal result elements in the stylesheet or by xsl:element elements. The xsl:element attribute has a required name attribute that specifies the name of the attribute. The name attribute is interpreted as an attribute value template It adds an attribute node to the containing result element node. The content of the xsl:attribute element is a template for the value of the created attribute.
The following are all errors:
- Adding an attribute to an element after children have been added to it; implementations may either signal the error or ignore the attribute.
- Including nodes other than text nodes in the value of an attribute; implementations may either signal the error or ignore the added nodes.
- Adding an attribute that has the same name as an attribute already added; implementations may either signal the error or ignore the duplicate attribute.
- Adding an attribute to a node that is not an element; implementations may either signal the error or ignore the attribute.

Creating Text
A template can also contain text nodes. Each text node in a template remaining after whitespace has been stripped as specified in will create a text node with the same value in the result tree. Adjacent text nodes in the result tree are automatically merged.
Note that text is processed at the tree level. Thus, markup of &lt; in a template will be represented in the stylesheet tree by a text node that includes the character <. This will create a text node in the result tree that contains a < character, which will be represented by the markup &lt; (or an equivalent character reference) when the result tree is externalized as an XML document.
Literal data characters may also be wrapped in an xsl:text element. This wrapping may change what whitespace characters are stripped (see ) but does not affect how the characters are handled by the XSL processor thereafter.

Creating Processing Instructions
The xsl:pi element is instantiated to create a processing instruction node. The content of the xsl:pi element is a template for the value of the processing instruction node. The xsl:pi element has a required name attribute that specifies the name of the processing instruction node. The value of the name attribute is interpreted as an attribute value template.
For example, this
<xsl:pi name="xml-stylesheet">href="book.css" type="text/css"</xsl:pi>
would create the processing instruction
<?xml-stylesheet href="book.css" type="text/css"?>
It is an error if instantiating the content of xsl:pi creates anything other than characters. An XSL processor may signal the error; if it does not signal the error, it must recover by ignoring the offending nodes together with their content.
It is an error if the content of the xsl:pi contains the string ?>. An XSL processor may signal the error; if it does not signal the error, it must recover by inserting a space after any occurrence of ? that is followed by another >.

Creating Comments
The xsl:comment element is instantiated to create a comment node in the result tree. The content of the xsl:comment element is a template for the value of the comment node.
For example, this
<xsl:comment>This file is automatically generated. Do not edit!</xsl:comment>
would create the comment
<!--This file is automatically generated. Do not edit!-->
It is an error if instantiating the content of xsl:comment creates anything other than characters. An XSL processor may signal the error; if it does not signal the error, it must recover by ignoring the offending nodes together with their content.
It is an error if the content of the xsl:comment contains the string --. An XSL processor may signal the error; if it does not signal the error, it must recover by inserting a space after any occurrence of - that is followed by another -.

Processing with Template Rules
This example creates a block for a chapter element and then processes its immediate children.
<xsl:template match="chapter">
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>
In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node, including text nodes. However, text nodes that have been stripped as specified in will not be processed.
There is no WG consensus on the use xsl:apply-templates without a select attribute to process all children of a node.
A select attribute can be used to process nodes selected by a pattern instead of all children. The value of the select attribute is a select pattern. The following example processes all of the author children of the author-group:
<xsl:template match="author-group">
  <fo:sequence>
    <xsl:apply-templates select="author"/>
  </fo:sequence>
</xsl:template>
The pattern controls the depth at which matches occur. The following example processes all of the first-names of the authors that are direct children of author-group:
<xsl:template match="author-group">
  <fo:sequence>
    <xsl:apply-templates select="author/first-name"/>
  </fo:sequence>
</xsl:template>
// can be used in the pattern to allow the matches to occur at arbitrary depths.
This example processes all of the heading elements contained in the book element.
<xsl:template match="book">
  <fo:block>
    <xsl:apply-templates select=".//heading"/>
  </fo:block>
</xsl:template>
An AncestorExpr in the pattern allows the processing of elements that are not descendants of the current node. This example finds an employee's department and then processes the group children of the department.
<xsl:template match="employee">
  <fo:block>
    Employee <xsl:apply-templates select="name"/> belongs to group
    <xsl:apply-templates select="ancestor(department)/group"/>
  </fo:block>
</xsl:template>
This example assumes that a department element contains group and employee elements (at some level). When processing the employee elements, the AncestorExpr in the pattern allows navigation upward to the department element in order to extract the information about the group to which the employee belongs.
An IdExpr allows processing of elements with a specific ID. For example, this template rule applies to elements with the ID cfo; the second xsl:apply-templates element processes the name child of the element with ID ceo:
<xsl:template match="id(cfo)">
  <xsl:apply-templates select="name"/> reports to <xsl:apply-templates select="id(ceo)/name"/>
</xsl:template>
Multiple xsl:apply-templates elements can be used within a single template to do simple reordering. The following example creates two HTML tables. The first table is filled with domestic sales while the second table is filled with foreign sales.
<xsl:template match="product">
  <TABLE>
    <xsl:apply-templates select="sales/domestic"/>
  </TABLE>
  <TABLE>
    <xsl:apply-templates select="sales/foreign"/>
  </TABLE>
</xsl:template>
It is possible for there to be two matching descendants where one is a descendant of the other. This case is not treated specially: both descendants will be processed as usual. For example, given a source document
<doc><div><div></div></div></doc>
the rule
<xsl:template match="doc">
  <xsl:apply-templates select=".//div"/>
</xsl:template>
will process both the outer div and inner div elements.
Use of select patterns in xsl:apply-templates can lead to infinite loops. It is an error if, during the invocation of a rule for an element, that same rule is invoked again for that element. An XSL processor may signal the error; if it does not signal the error, it must recover by creating an empty result tree structure for the nested invocation.
What mechanisms should be provided for selecting elements for processing? For example, how can elements specified indirectly be handled? Suppose there's an xref element with a ref attribute that specifies the ID of a div element. The template for xref needs to select title child of the div element referenced by the ref attribute. Should it be possible to select elements in other XML documents?

Direct Processing
When the result has a known regular structure, it is useful to be able to specify directly the template for selected elements. The xsl:for-each element contains a template which is instantiated for each element selected by the pattern specified by the select attribute.
Make it clear that it changes the current node.
For example, given an XML document with this structure
<customers>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
</customers>
the following would create an HTML document containing a table with a row for each customer element
<xsl:template match="/">
  <HTML>
    <HEAD>
      <TITLE>Customers</TITLE>
    </HEAD>
    <BODY>
      <TABLE>
	<TBODY>
	  <xsl:for-each select="customers/customer">
	    <TR>
	      <TH>
		<xsl:apply-templates select="name"/>
	      </TH>
	      <xsl:for-each select="order">
		<TD>
		  <xsl:apply-templates/>
		</TD>
	      </xsl:for-each>
	    </TR>
	  </xsl:for-each>
	</TBODY>
      </TABLE>
    </BODY>
  </HTML>
</xsl:template>
As with xsl:apply-templates the pattern is a select pattern. The select attribute is required.

Processing Modes
Processing modes allow an element to processed multiple times, each time producing a different result.
Both xsl:template and xsl:apply-templates have an optional mode attribute whose value is a name. If an xsl:apply-templates element has a mode attribute, then it applies only those template rules from xsl:template elements that have a mode attribute with the same value; if an xsl:apply-templates element does not have a mode attribute, then it applies only those template rules from xsl:template elements that do not have a a mode attribute.
If there is no matching template, then the built-in template rule is applied, even if a mode attribute was specified in xsl:apply-templates.
Add some examples.

Sorting
Sorting is specified by adding xsl:sort elements as children of xsl:apply-templates or xsl:for-each. The first xsl:sort child specifies the primary sort key, the second xsl:sort child specifies the secondary sort key and so on. When xsl:apply-templates or xsl:for-each has one or more xsl:sort children, then instead of processing the selected elements in document order, it sorts the elements according to the specified sort keys and then processes them in sorted order. When used in xsl:for-each, xsl:sort elements must occur first.
xsl:sort has a select attribute whose value is a select pattern. For each node to be processed, the select pattern is evaluated with that node as the current node. The value of the first selected node is used as the sort key for that node. The default value of the code select attribute is . (which addresses the current element).
This string serves as a sort key for the node. The following optional attributes on xsl:sort control how the list of sort keys are sorted:
- order specifies whether the strings should be sorted in ascending or descending order; ascending specifies ascending order; descending specifies descending order; the default is ascending
- lang specifies the language of the sort keys; it has the same range of values as xml:lang ; if no lang value is specified, the language should be determined from the system environment
- data-type specifies the data type of the strings; the following values are allowed
  - text specifies that the sort keys should be sorted lexicograhically in the culturally correct manner for the language specified by lang
  - number specifies that the sort keys should be converted to numbers and then sorted according to the numeric value; the value specified by lang can be used to assist in the conversion to numbers
The default value is text.
We plan to leverage the work on XML schemas to define further values in the future.
- case-order has the value upper-first or lower-first; this applies when data-type="text", and specifies that upper-case characters should sort before lower-case letters or vice-versa respectively. For example, if lang="en" then A a B b are sorted with case-order="upper-first" and a A b B are sorted with case-order="lower-first". The default value is language dependent.
We plan also to add an attribute whose value is a label identifying the sorting scheme, to be specified by the I18N WG.
The values of all of the above attributes are interpreted as attribute value templates.
It is recommended that implementors consult for information on internationalized sorting.
The sort must be stable: in the sorted list of nodes, any sublist that has sort keys that all compare equal must be in document order.
For example, suppose an employee database has the form
<employees>
  <employee>
    <name>
      <first>James</first>
      <last>Clark</last>
    </name>
    ...
  </employee>
</employees>

Then a list of employees sorted by name could be generated using:
<xsl:template match="employees">
 <ul>
  <xsl:apply-templates select="employee">
    <xsl:sort select="name/last"/>
    <xsl:sort select="name/first"/>
  </xsl:apply-templates>
  </ul>
</xsl:template>

<xsl:template match="employee">
 <li>
  <xsl:value-of select="name/first"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="name/last"/>
 </li>
</xsl:template>

Numbering

Numbering in the Source Tree
The xsl:number element does numbering based on the position of the current node in the source tree.
The xsl:number element can have the following attributes:
- The level attribute specifies what levels of the source tree should be considered; it has the values single, multi or any. The default is single.
- The count attribute is a match pattern that specifies what elements should be counted at those levels. The count attribute defaults to the element type name of the current node.
- The from attribute is a match pattern that specifies where counting starts from.
In addition the xsl:number element has the attributes specified in for number to string conversion.
The xsl:number element first constructs a list of positive integers using the level, count and from attributes:
- When level="single", it goes up to the nearest ancestor (including the current node as its own ancestor) that matches the count pattern, and constructs a list of length one containing one plus the number of preceding siblings of that ancestor that match the count pattern. If there is no such ancestor, it constructs an empty list. If the from attribute is specified, then the only ancestors that are searched are those that are descendants of the nearest ancestor that matches the from pattern.
- When level="multi", it constructs a list of all ancestors of the current node in document order followed by the element itself; it then selects from the list those elements that match the count pattern; it then maps each element of the list to one plus the number of preceding siblings of that element that match the count pattern. If the from attribute is specified, then the only ancestors that are searched are those that are descendants of the nearest ancestor that matches the from pattern.
- When level="any", it constructs a list of length one containing one plus the number of elements at any level of the document that start before this node and that match the count pattern. If the from attribute is specified, then only elements after the first element before this element that match the from pattern are considered.
The list of numbers is then converted into a string using the attributes specified in ; when used with xsl:number the value of each of these attributes is interpreted as an attribute value template. After conversion, the resulting string is inserted in the result tree.
Allowing them to be attribute value templates isn't consistent with the current DTD: the declared values would all have to be CDATA, and we couldn't use xml:lang because the XML spec doesn't allow the value to be expressed as a template.
The following would number the items in an ordered list:
<xsl:template match="ol/item">
  <fo:block>
    <xsl:number/><xsl:text>. </xsl:text><xsl:apply-templates/>
  </fo:block>
<xsl:template>
The following two rules would number title elements. This is intended for a document that contains a sequence of chapters followed by a sequence of appendices, where both chapters and appendices contain sections which in turn contain subsections. Chapters are numbered 1, 2, 3; appendices are numbered A, B, C; sections in chapters are numbered 1.1, 1.2, 1.3; sections in appendices are numbered A.1, A.2, A.3.
<xsl:template match="title">
  <fo:block>
     <xsl:number level="multi"
                 count="chapter|section|subsection"
                 format="1.1. "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

<xsl:template match="appendix//title" priority="1">
  <fo:block>
     <xsl:number level="multi"
                 count="appendix|section|subsection"
                 format="A.1. "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>
The following example numbers notes sequentially within a chapter:
<xsl:template match="note">
  <fo:block>
     <xsl:number level="any" from="chapter" format="(1) "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>
The following example would number H4 elements in HTML with a three-part label:
<xsl:template match="H4">
 <fo:block>
   <xsl:number level="any" from="H1" count="H2"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H2" count="H3"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H3" count="H4"/>
   <xsl:text> </xsl:text>
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

Numbering in the Result Tree
The root node of the result and each result element has a set of named counters (a mapping from names to integers).
Counter values are inserted using xsl:counter and xsl:counters elements. The name of the counter is specified with the name attribute. xsl:counter first constructs a list of length one containing the value of the named counter from the nearest ancestor in the result tree that has a counter with the specified name; xsl:counters first constructs a list containing, for each ancestor in the result tree that has a counter with the specified name, the value of named counter from that ancestor. xsl:counter and xsl:counters then convert the list of numbers into a string using the attributes specified in ; when used with xsl:counter and xsl:counters the value of each of these attributes is interpreted as an attribute value template.
Counters are incremented using the xsl:counter-increment element. The name attribute specifies the name of the counter to be incremented. It finds the nearest ancestor in the result tree that has a counter with the specified name and increments that; if there is no such ancestor, it adds a counter with a value of zero to the document root and then increments it. The counter is incremented by 1 by default, but this can be changed using the amount attribute.
The xsl:counter-reset element sets the value of a counter in the current named counter set. The current named counter set is the set of named counters of the containing element in the result tree or of the document root if there is no containing element. If the current named counter set doesn't contain a counter of that name, a counter is added to it, otherwise the existing value is changed. The name of the counter to be set is specified by the name attribute. The value to set it to is specified by the value attribute; this defaults to 0.
The xsl:counter-scope element is a phantom result element: it behaves just like a normal result element for the purposes of result numbering in that it is considered part of the result tree and has a set of named counters, but doesn't actually create a result element. This is for when the result tree doesn't have enough structure for counting.
The numbering may be performed in the tree construction process or may be left for the formatting process.
These facilities for result tree numbering are based on the facilities for automatic numbering in .
The following example would number notes sequentially throughout a document:
<xsl:template match="note">
  <xsl:text> (Note </xsl:text>
  <xsl:counter-increment name="note"/>
  <xsl:counter name="note"/>
  <xsl:text>).</xsl:text>
</xsl:template>
The following would turn ordered lists into definition lists:
<xsl:template match="OL">
  <dl>
    <xsl:counter-reset name="li"/>
    <xsl:apply-templates/>
  </dl>
</xsl:template>

<xsl:template match="LI">
  <xsl:counter-increment name="li"/>
  <dt><xsl:counter name="li"/></dt>
  <dd><xsl:apply-templates/></dd>
</xsl:template>
The following would do HTML style numbering:
<xsl:template match="h2">
  <xsl:counter-increment name="h2"/>
  <p>
    <xsl:counter name="h2"/>
    <xsl:text>. </xsl:text>
    <xsl:apply-templates/>
  </p>
  <xsl:counter-reset name="h3"/>
</xsl:template>

<xsl:template match="h3">
  <xsl:counter-increment name="h3"/>
  <p>
    <xsl:counter name="h2"/>
    <xsl:text>.</xsl:text>
    <xsl:counter name="h3"/>
    <xsl:text>. </xsl:text>
    <xsl:apply-templates/>
  </p>
  <xsl:counter-reset name="h4"/>
</xsl:template>

<xsl:template match="h4">
  <xsl:counter-increment name="h4"/>
  <p>
    <xsl:counter name="h2"/>
    <xsl:text>.</xsl:text>
    <xsl:counter name="h3"/>
    <xsl:text>.</xsl:text>
    <xsl:counter name="h4"/>
    <xsl:text>.</xsl:text>
    <xsl:apply-templates/>
  </p>
</xsl:template>
The following would deal with recursive divs each with a title child:
<xsl:template match="div">
  <div>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="title">
 <p>
  <xsl:counter-increment name="div"/>
  <xsl:counters name="div" format="1.1. "/>
  <xsl:apply-templates/>
 </p>
 <xsl:counter-reset name="div"/>
</xsl:template>

Number to String Conversion Attributes
The following attributes are used to control conversion of a list of numbers into a string. The numbers are integers greater than 0. The attributes are all optional.
The main attribute is format. The default value for the format attribute is 1. The format attribute is split into a sequence of tokens where each token is a maximal sequence of alphanumeric characters or a maximal sequence of non-alphanumeric characters. Alphanumeric means any character that has a Unicode category of Nd, Nl, No, Lu, Ll, Lt, Lm or Lo. The alphanumeric tokens (format tokens) specify the format to be used for each number in the list. If the first token is a non-alphanumeric token, then the constructed string will start with that token; if the last token is non-alphanumeric token, then the constructed string will end with that token. Non-alphanumeric tokens that occur between two format tokens are separator tokens that are used to join numbers in the list. The n-th format token will be used to format the n-th number in the list. If there are more numbers than format tokens, then the last format token will be used to format remaining numbers. If there are no format tokens, then a format token of 1 is used to format all numbers. The format token specifies the string to be used to represent the number 1. Each number after the first will be separated from the preceding number by the separator token preceding the format token used to format that number, or, if there are no separator tokens, then by ..
Format tokens are a superset of the allowed values for the type attribute for the OL element in HTML 4.0 and are interpreted as follows:
- Any token where the last character has a decimal digit value of 1 (as specified in the Unicode 2.0 character property database), and the Unicode value of preceding characters is one less than the Unicode value of the last character. This generates a decimal representation of the number where each number is at least as long as the format token. Thus a format token 1 generates the sequence 1 2 ... 10 11 12 ..., and a format token 01 generates the sequence 01 02 ... 09 10 11 12 ... 99 100 101.
- A format token A generates the sequence A B C ... Z AA AB AC....
- A format token a generates the sequence a b c ... z aa ab ac....
- A format token i generates the sequence i ii iii iv v vi vii vii ix x ....
- A format token I generates the sequence I II III IV V VI VII VII IX X ....
- Any other format token indicates a numbering sequence that starts with that token. If an implementation does not support a numbering system that starts with that token, it must use a format token of 1.
When numbering with an alphabetic sequence, the xml:lang attribute specifies which language's alphabet is to be used.
This can be considered as specifying the language of the value of the format attribute and hence is consistent with the semantics of xml:lang.
The letter-value attribute disambiguates between numbering schemes that use letters. In many languages there are two commonly used numbering schemes that use letters. One numbering scheme assigns numeric values to letters in alphabetic sequence, and the other assigns numeric values to each letter in some other manner. In English, these would correspond to the numbering sequences specified by the format tokens a and i. In some languages the first member of each sequence is the same, and so the format token alone would be ambiguous. A value of alphabetic specifies the alphabetic sequence; a value of other specifies the other sequence.
The digit-group-sep attribute gives the separator between groups of digits, and the optional n-digits-per-group specifies the number of digits per group. For example, digit-group-sep="," and n-digits-per-group="3" would produce numbers of the form 1,000,000.
The sequence-src attribute gives the URI of a text resource that contains a whitespace separated list of the members of the numbering sequence.
Specify what should happen when the sequence runs out.
Here are some examples of conversion specifications:
- format="&#x30A2;" specifies Katakana numbering
- format="&#x30A4;" specifies Katakana numbering in the iroha order
- format="&#x0E51;" specifies numbering with Thai digits
- format="&#x05D0;" letter-value="other" specifies traditional Hebrew numbering
- format="&#x10D0;" letter-value="other" specifies Georgian numbering
- format="&#x03B1;" letter-value="other" specifies classical Greek numbering
- format="&#x0430;" letter-value="other" specifies Old Slavic numbering

Conditionals within a Template
There are two instructions in XSL which support conditional processing in a template: xsl:if and xsl:choose. The xsl:if instruction provides simple if-then conditionality; the xsl:choose instruction supports selection of one choice when there are several possibilities.

Conditional Processing with xsl:if
The xsl:if element has a single attribute, test which specifies a select pattern. The content is a template. If the pattern selects a non-empty list of elements, then the content is instantiated; otherwise nothing is created. In the following example, the names in a group of names are formatted as a comma separated list:
<xsl:template match="namelist/name">
  <xsl:apply-templates/>
  <xsl:if test=".[not(last-of-type())]">, </xsl:if>
</xsl:template>

Conditional Processing with xsl:choose
The xsl:choose element selects one among a number of possible alternatives. It consists of a series of xsl:when elements followed by an optional xsl:otherwise element. Each xsl:when element has a single attribute, test, which specifies a select pattern; the test is treated as true if the pattern selects a non-empty list of elements. The content of the xsl:when and xsl:otherwise elements is a template. When an xsl:choose element is processed, each of the xsl:when elements is tested in turn. The content of the first, and only the first, xsl:when element whose test is true is instantiated. If no xsl:when is true, the content of the xsl:otherwise element is instantiated. If no xsl:when element is true, and no xsl:otherwise element is present, nothing is created.
The following example enumerates items in an ordered list using arabic numerals, letters, or roman numerals depending on the depth to which the ordered lists are nested.
<xsl:template match="orderedlist/listitem">
  <fo:list-item indent-start='2pi'>
    <fo:list-item-label>
      <xsl:choose>
        <xsl:when test='ancestor(orderedlist/orderedlist)'>
          <xsl:number format="i"/>
        </xsl:when>
        <xsl:when test='ancestor(orderedlist)'>
          <xsl:number format="a"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:number format="1"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>. </xsl:text>
    </fo:list-item-label>
    <fo:list-item-body>
      <xsl:apply-templates/>
    </fo:list-item-body>
  </fo:list-item>
</xsl:template>

Copying
The xsl:copy element provides an easy way of copying the current node. The xsl:copy element is replaced by a copy of the current node. Only the children of the node are not automatically copied. Everything else about the current node, including the attribute nodes and the namespace nodes, are automatically copied. The content of the xsl:copy element is a template for the children of the created node; the content is not used for nodes of types that do not have children (attributes, text, comments and processing instructions).
The root node is treated specially because the root node of the result tree is created implicitly. When the current node is the root node, xsl:copy will not create a root node, but will just use the content template.
For example, the identity transformation can be written using xsl:copy:
<xsl:template match="*|comment()|pi()">
  <xsl:copy>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>
Should there be some way for xsl:copy to control the copying of attributes?

Computing Generated Text
Within a template, the xsl:value-of element can be used to compute generated text, for example by extracting text from the source tree or by inserting the value of a string constant. The xsl:value-of element does this with a string expression that is specified as the value of the select attribute. String expressions can also be used inside attribute values of literal result elements by enclosing the string expression in curly brace ({}).

String Expressions

String Expressions
StringExpr
SelectExpr
| NameExpr
| ConstantRef
| MacroArgRef
The value of a string expression that is a pattern is the value of the first node selected by the pattern. The value of each kind of node is described in . If no nodes are selected by the pattern, then the value is the empty string. The pattern is a select pattern.
Do we need a resolve(pattern) 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?

Name Expression
NameExpr
'name' '(' SelectExpr ')'
The value of a NameExpr is the expanded name of the first node selected by the SelectExpr. If no nodes are selected or the first node does not have a name, then the value is the empty string. If the expanded name has a null URI, then the value is just the local name. If the expanded name has a non-null URI, the the value is the URI followed by the character # followed by the local name.

Using String Expressions with xsl:value-of
The xsl:value-of element is replaced by the value of the string expression specified by the select attribute. The select attribute is required.
For example, the following creates an HTML paragraph from a person element with first-name and surname attributes.
<xsl:template match="person">
  <P>
   <xsl:value-of select="@first-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="@surname"/>
  </P>
</xsl:template>
For example, the following creates an HTML paragraph from a person element with first-name and surname children elements.
<xsl:template match="person">
  <P>
   <xsl:value-of select="first-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="surname"/>
  </P>
</xsl:template>
The following precedes each procedure element with a paragraph containing the security level of the procedure. It assumes that the security level that applies to a procedure is determined by a security attribute on an ancestor element of the procedure. It also assumes that if more than one ancestor has a security attribute then the security level is determined by the closest such ancestor of the procedure.
<xsl:template match="procedure">
  <fo:block>
    <xsl:value-of select="ancestor(*[@security])/@security"/>
  </fo:block>
  <xsl:apply-templates/>
</xsl:template>
Unless an element counts as one of its own ancestors, using ancestor(*[@security])/@security won't work to get the inherited value of an attribute. We could either say ancestor always includes the current node; alternatively we could provide a variant of ancestor that does include the current node; alternatively we could provide a select pattern of the form inherited-attribute('security').

Attribute Value Templates
In an attribute value that is interpreted as an attribute value template, such as an attribute of a literal result element, string expressions can be used by surrounding the string expression with curly braces ({}). The attribute value template is instantiated by replacing the string expression together with surrounding curly braces by the value of the string expression.
The following example creates an IMG result element from a photograph element in the source; the value of the SRC attribute of the IMG element is computed from the value of the image-dir constant and the content of the href child of the photograph element; the value of the WIDTH attribute of the IMG element is computed from the value of the the width attribute of the size child of the photograph element:
<xsl:constant name="image-dir" value="/images"/>

<xsl:template match="photograph">
<IMG SRC="{constant(image-dir)}/{href}" WIDTH="{size/@width}"/>
</xsl:template>
With this source
<photograph>
  <href>headquarters.jpg</href>
  <size width="300"/>
</photograph>
the result would be
<IMG SRC="/images/headquarters.jpg" WIDTH="300"/>
When an attribute value template is instantiated, a double left or right curly brace outside a string expression will be replaced by a single curly brace. It is an error if a right curly brace occurs in an attribute value template outside a string expression without being followed by a second right curly brace; an XSL processor may signal the error or recover by treating the right curly brace as if it had been doubled. A right curly brace inside an Literal in a string expression is not recognized as terminating the string expression.
Curly braces are not recognized recursively inside string expressions. For example:
<a href="#{id({@ref})/title}">
is not allowed. Instead use simply:
<a href="#{id(@ref)/title}">

String Constants
Global string constants may be defined using a constant element. The name attribute specifies the name of the constant, and the value attribute specified the value.
A stylesheet must not contain more than one definition of a constant with the same name and same importance. A definition of a constant will not be used if there is another definition of a constant with the same name and higher importance.
String constants are referenced using a ConstantRef string expression.

String Constant References
ConstantRef
'constant' '(' NCName ')'
<xsl:constant name="para-font-size" value="12pt"/>

<xsl:template match="para">
 <fo:block font-size="{constant(para-font-size)}">
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

Should there be a way to define local constants?
The value attribute is interpreted as an attribute value template. If the value of a constant definition x references a constant y, then the value for y must be computed before the value of x. It is an error if it is impossible to do this for all constant definitions because of dependency cycles.

Macros
Should macros be called something else?
Parts of templates can also be factored out of similar rules into macros for reuse. Macros allow authors to create aggregate result fragments and refer to the composite as if it were a single object. In this example, a macro is defined for a boxed paragraph with the word Warning! preceding the contents. The macro is referenced from a rule for warning elements.
<xsl:macro name="warning-para">
  <fo:block-level-box>
    <fo:block>
      <xsl:text>Warning! </xsl:text>
      <xsl:contents/>
    </fo:block>
  </fo:block-level-box>
</xsl:macro>

<xsl:template match="warning">
  <xsl:invoke macro="warning-para">
    <xsl:apply-templates/>
  </xsl-invoke>
</xsl:template>
Macros are defined using the macro element. The name attribute specifies the name of the macro being defined. The content of the macro element is a template, called the body of the macro. A macro is invoked using the xsl:invoke element; the content of xsl:invoke is a template. The name of the macro to be invoked is given by the macro attribute. Invoking a macro first instantiates the content of xsl:invoke. It then instantiates the body of the invoked macro passing it the result tree fragment created by the instantiation of the content of xsl:invoke; this fragment can be inserted in the body of the macro using the xsl:contents element.
Macros allow named arguments to be declared with the xsl:macro-arg element; the name attribute specifies the argument name, and the optional default attribute specifies the default value for the argument. Within the body of a macro, macro arguments are referenced using a MacroArgRef string expression. It is an error to refer to a macro argument that has not been declared. An XSL processor may signal the error; if it does not signal the error, it must recover by using an empty string. Arguments are supplied to a macro invocation using the code xsl:arg element; the name attribute specifies the argument name, and the value attribute specifies the argument value. It is an error to supply an argument to a macro invocation if the macro did not declare an argument of that name. An XSL processor may signal the error; if it does not signal the error, it must recover by ignoring the argument. The value attribute of xsl:arg and the default attribute of xsl:macro-arg are interpreted as attribute value templates; they can contain string expressions in curly braces as with literal result elements.

Macro Argument References
MacroArgRef
'arg' '(' NCName ')'
This example defines a macro for a numbered-block with an argument to control the format of the number.
<xsl:macro name="numbered-block">
  <xsl:macro-arg name="format" default="1. "/>
  <xsl:number format="{arg(format)}"/>
  <fo:block/>
    <xsl:contents/>
  </fo:block>
</xsl:macro>

<xsl:template match="appendix/title">
  <xsl:invoke macro="numbered-block">
    <xsl:arg name="format" value="A. "/>
    <xsl:apply-templates/>
  </xsl:invoke>
</xsl:template>
It is an error if a stylesheet contains more than one definition of a macro with the same name and same importance. An XSL processor may signal the error; if it does not signal the error, if must recover by choosing from amongst the definitions with highest importance the one that occurs last in the stylesheet.
The proposal used the same element for declaring macro arguments and for invoking them. Should these be separate elements and if so what should they be called?

Combining Stylesheets
XSL provides two mechanisms to combine stylesheets:
an import mechanism that allows stylesheets to override each other, and
an inclusion mechanism that allows stylesheets to be textually combined.

Stylesheet Import
An XSL stylesheet may contain xsl:import elements. All the xsl:import elements must occur at the beginning of the stylesheet. The xsl:import element has an href attribute whose value is the URI of a stylesheet to be imported. A relative URI is resolved relative to the base URI of the xsl:import element (see ).
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
  <xsl:import href="article.xsl"/>
  <xsl:import href="bigfont.xsl"/>
  <xsl:attribute-set name="note-style">
    <xsl:attribute name="font-style">italic</xsl:attribute>
  </xsl:attribute-set>
</xsl:stylesheet>
Rules and definitions in the importing stylesheet are defined to be more important than rules and definitions in any imported stylesheets. Also rules and definitions in one imported stylesheet are defined to be more important than rules and definitions in previous imported stylesheets.
In general a more important rule or definition takes precedence over a less important rule or definition. This is defined in detail for each kind of rule and definition.
Should there be an XSL defined element that can be used to divide a stylesheet into parts, each of which is treated as if it were separately imported for precedence purposes?
Provide a way for a stylesheet to import a stylesheet that is embedded in the document.
Should we provide media-dependent imports as in CSS?
Say something about the case where the same stylesheet gets imported twice. This should be treated the same as importing a stylesheet with the same content but different URIs. What about import loops?
xsl:apply-templates processes the current node using only template rules that were imported into the stylesheet containing the current rule; the current node is processed in the current rule's mode.
Expand this.

Stylesheet Inclusion
An XSL stylesheet may include another XSL stylesheet using an xsl:include element. The xsl:include element has an href attribute whose value is the URI of a stylesheet to be included. A relative URI is resolved relative to the base URI of the xsl:include element (see ). The xsl:include element can occur as the child of the xsl:stylesheet element at any point after all xsl:import elements.
The inclusion works at the XML tree level. The resource located by the href attribute value is parsed as an XML document, and the children of the xsl:stylesheet element in this document replace the xsl:include element in the including document. Also any xsl:import elements in the included document are moved up in the including document to after any existing xsl:import elements in the including document. Unlike with xsl:import, the fact that rules or definitions are included does not affect the way they are processed.
What happens when a stylesheet directly or indirectly includes itself?

Embedding Stylesheets
Normally an XSL stylesheet is a complete XML document with the xsl:stylesheet element as the document element. However an XSL stylesheet may also be embedded in another resource. Two forms of embedding are possible:
the XSL stylesheet may be textually embedded in a non-XML resource, or
the xsl:stylesheet element may occur in an XML document other than as the document element.
In the second case, the possibility arises of documents with inline style, that is documents that specify their own style. XSL does not define a specific mechanism for this. This is because this can be done by means of a general purpose mechanism for associating stylesheets with documents provided that:
the mechanism allows a part of a resource to be specified as the stylesheet, for example by using a URI with a fragment identifier, and
the mechanism can itself can be embedded in the document, for example as a processing instruction.
It is not in the scope of XSL to define such a mechanism.
This is because the mechanism should be independent of any one stylesheet mechanism.
The xsl:stylesheet element may have an ID attribute that specifies a unique identifier.
In order for such an attribute to be used with the id XPointer location term, it must actually be declared in the DTD as being an ID.
The following example shows how inline style can be accomplished using the xml-stylesheet processing instruction mechanism for associating a stylesheet with an XML document. The URI uses an XPointer in a fragment identifier to locate the xsl:stylesheet element.
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="#id(style1)"?>
<!DOCTYPE doc SYSTEM "doc.dtd">
<doc>
<head>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" id="style1">
<xsl:import href="doc.xsl"/>
<xsl:template match="id(foo)">
 <fo:block font-weight="bold"><xsl:apply-templates/></fo:block>
</xsl:template>
</xsl:stylesheet>
</head>
<body>
<para id="foo">
...
</para>
</body>
</doc>

The type pseudo-attribute in the xml-stylesheet processing instruction identifies the stylesheet language, not the content type of the resource of which the stylesheet is a part.

Extensibility
This section will describe an extensibility mechanism for the tree construction process.
Should there be some extensibility mechanism for the tree construction process? If so, how should it work? Should it be language independent?

DTD for XSL Stylesheets
The following entity can be used to construct a DTD for XSL stylesheets that create instances of a particular result DTD. Before referencing the entity, the stylesheet DTD must define a result-elements parameter entity listing the allowed result element types. For example:
<!ENTITY % result-elements "
  | fo:sequence
  | fo:block
">
<!ENTITY % instructions "
  | xsl:apply-templates
  | xsl:apply-imports
  | xsl:for-each
  | xsl:value-of
  | xsl:number
  | xsl:counter
  | xsl:counters
  | xsl:counter-increment
  | xsl:counter-reset
  | xsl:counter-scope
  | xsl:choose
  | xsl:if
  | xsl:contents
  | xsl:invoke
  | xsl:text
  | xsl:pi
  | xsl:comment
  | xsl:element
  | xsl:attribute
  | xsl:copy
">

<!ENTITY % template "
 (#PCDATA
  %instructions;
  %result-elements;)*
">

<!ENTITY % space-att "xml:space (default|preserve) #IMPLIED">

<!ELEMENT xsl:stylesheet
 (xsl:import*,
  (xsl:include
  | xsl:id
  | xsl:strip-space
  | xsl:preserve-space
  | xsl:macro
  | xsl:attribute-set
  | xsl:constant
  | xsl:template)*)
>

<!ATTLIST xsl:stylesheet
  result-ns NMTOKEN #IMPLIED
  default-space (preserve|strip) "preserve"
  indent-result (yes|no) "no"
  id ID #IMPLIED
  xmlns:xsl CDATA #FIXED "http://www.w3.org/TR/WD-xsl"
  %space-att;
>

<!-- Used for attribute values that are URIs.-->
<!ENTITY % URI "CDATA">

<!-- Used for attribute values that are patterns.-->
<!ENTITY % pattern "CDATA">

<!-- Used for attribute values that are a priority. -->
<!ENTITY % priority "NMTOKEN">

<!ELEMENT xsl:import EMPTY>
<!ATTLIST xsl:import href %URI; #REQUIRED>

<!ELEMENT xsl:include EMPTY>
<!ATTLIST xsl:include href %URI; #REQUIRED>

<!ELEMENT xsl:id EMPTY>
<!ATTLIST xsl:id
  attribute NMTOKEN #REQUIRED
  element NMTOKEN #IMPLIED
>

<!ELEMENT xsl:strip-space EMPTY>
<!ATTLIST xsl:strip-space element NMTOKEN #REQUIRED>

<!ELEMENT xsl:preserve-space EMPTY>
<!ATTLIST xsl:preserve-space element NMTOKEN #REQUIRED>

<!ELEMENT xsl:template %template;>
<!ATTLIST xsl:template
  match %pattern; #REQUIRED
  priority %priority; #IMPLIED
  mode NMTOKEN #IMPLIED
  %space-att;
>

<!ELEMENT xsl:value-of EMPTY>
<!ATTLIST xsl:value-of select CDATA #IMPLIED>

<!ENTITY % conversion-atts '
   format CDATA "1"
   xml:lang NMTOKEN #IMPLIED
   letter-value (alphabetic|other) #IMPLIED
   digit-group-sep CDATA #IMPLIED
   n-digits-per-group NMTOKEN #IMPLIED
   sequence-src %URI; #IMPLIED
'>

<!ELEMENT xsl:number EMPTY>
<!ATTLIST xsl:number
   level (single|multi|any) "single"
   count CDATA #IMPLIED
   from CDATA #IMPLIED
   %conversion-atts;
>

<!ELEMENT xsl:counter EMPTY>
<!ATTLIST xsl:counter
  name NMTOKEN #REQUIRED
  %conversion-atts;
>

<!ELEMENT xsl:counters EMPTY>
<!ATTLIST xsl:counters
  name NMTOKEN #REQUIRED
  %conversion-atts;
>

<!ELEMENT xsl:counter-increment EMPTY>
<!ATTLIST xsl:counter-increment
  name NMTOKEN #REQUIRED
  amount NMTOKEN #IMPLIED
>

<!ELEMENT xsl:counter-reset EMPTY>
<!ATTLIST xsl:counter-reset
  name NMTOKEN #REQUIRED
  value NMTOKEN #IMPLIED
>

<!ELEMENT xsl:counter-scope %template;>
<!ATTLIST xsl:counter-scope %space-att;>

<!ELEMENT xsl:apply-templates (xsl:sort*)>
<!ATTLIST xsl:apply-templates
  select %pattern; #IMPLIED
  mode NMTOKEN #IMPLIED
>

<!ELEMENT xsl:apply-imports EMPTY>

<!-- xsl:sort cannot occur after any other elements or
any non-whitespace character -->

<!ELEMENT xsl:for-each
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:sort)*
>

<!ATTLIST xsl:for-each
  select %pattern; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:sort EMPTY>
<!ATTLIST xsl:sort
  select %pattern; "."
  lang CDATA #IMPLIED
  data-type (text|number) "text"
  order (ascending|descending) "ascending"
  case-order (upper-first|lower-first) #IMPLIED
>

<!ELEMENT xsl:if %template;>
<!ATTLIST xsl:if
  test %pattern; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:choose (xsl:when+, xsl:otherwise?)>
<!ATTLIST xsl:choose %space-att;>

<!ELEMENT xsl:when %template;>
<!ATTLIST xsl:when
  test %pattern; #REQUIRED
  %space-att;
>

<!ELEMENT xsl:otherwise %template;>
<!ATTLIST xsl:otherwise %space-att;>

<!ELEMENT xsl:attribute-set (xsl:attribute)*>
<!ATTLIST xsl:attribute-set
  name NMTOKEN #REQUIRED
>

<!ELEMENT xsl:constant EMPTY>
<!ATTLIST xsl:constant
  name NMTOKEN #REQUIRED
  value CDATA #REQUIRED
>

<!-- xsl:macro-arg cannot occur after any other elements or
any non-whitespace character -->

<!ELEMENT xsl:macro
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:macro-arg)*
>

<!ATTLIST xsl:macro
  name NMTOKEN #REQUIRED
  %space-att;
>

<!ELEMENT xsl:macro-arg EMPTY>
<!ATTLIST xsl:macro-arg
  name NMTOKEN #REQUIRED
  default CDATA #IMPLIED
>

<!-- This is allowed only within xsl:macro -->
<!ELEMENT xsl:contents EMPTY>

<!-- xsl:arg cannot occur after any other elements or
any non-whitespace character -->

<!ELEMENT xsl:invoke
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:arg)*
>

<!ATTLIST xsl:invoke
  macro NMTOKEN #REQUIRED
  %space-att;
>

<!ELEMENT xsl:arg EMPTY>
<!ATTLIST xsl:arg
  name NMTOKEN #REQUIRED
  value CDATA #REQUIRED
>

<!ELEMENT xsl:text (#PCDATA)>
<!ATTLIST xsl:text %space-att;>

<!ELEMENT xsl:pi %template;>
<!ATTLIST xsl:pi
  name CDATA #REQUIRED
  %space-att;
>

<!ELEMENT xsl:element %template;>
<!ATTLIST xsl:element
  name CDATA #REQUIRED
  %space-att;
>

<!ELEMENT xsl:attribute %template;>
<!ATTLIST xsl:attribute
  name CDATA #REQUIRED
  %space-att;
>

<!ELEMENT xsl:comment %template;>
<!ATTLIST xsl:comment %space-att;>

<!ELEMENT xsl:copy %template;>
<!ATTLIST xsl:copy %space-att;>

References

Normative References
World Wide Web Consortium. Extensible Markup Language (XML) 1.0. W3C Recommendation. See http://www.w3.org/TR/1998/REC-xml-19980210
World Wide Web Consortium. Namespaces in XML. W3C Working Draft. See http://www.w3.org/TR/WD-xml-names

Other References
World Wide Web Consortium. Cascading Style Sheets, level 2 (CSS2). W3C Recommendation. See http://www.w3.org/TR/1998/REC-CSS2-19980512
International Organization for Standardization, International Electrotechnical Commission. ISO/IEC 10179:1996. Document Style Semantics and Specification Language (DSSSL). International Standard.
Unicode Consortium. Draft Unicode Technical Report #10. Unicode Collation Algorithm. Draft Unicode Technical Report. See http://www.unicode.org/unicode/reports/tr10/index.html.
World Wide Web Consortium. Associating stylesheets with XML documents. W3C Working Draft. See http://www.w3.org/TR/WD-xml-stylesheet

Examples
The following is a simple but complete stylesheet.
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
                xmlns:fo="http://www.w3.org/TR/WD-xsl/FO"
                result-ns="fo"
                indent-result="yes">
<xsl:template match='/'>
 <fo:page-sequence font-family="serif">
  <fo:simple-page-master name='scrolling'/>
  <fo:queue queue-name='body'>
   <xsl:apply-templates/>
  </fo:queue>
 </fo:page-sequence>
</xsl:template>

<xsl:template match="title">
 <fo:block font-weight="bold">
  <xsl:apply-templates/>
 </fo:block>
</xsl:template>

<xsl:template match="p">
 <fo:block>
  <xsl:apply-templates/>
 </fo:block>
</xsl:template>

<xsl:template match="emph">
 <fo:sequence font-style="italic">
  <xsl:apply-templates/>
 </fo:sequence>
</xsl:template>

</xsl:stylesheet>
With the following source document
<doc>
<title>An example</title>
<p>This is a test.</p>
<p>This is <emph>another</emph> test.</p>
</doc>
it would produce the following result
<fo:page-sequence xmlns:fo="http://www.w3.org/TR/WD-xsl/FO"
  font-family="serif">
<fo:simple-page-master name="scrolling"/>
<fo:queue queue-name="body">
<fo:block font-weight="bold">An example</fo:block>
<fo:block>This is a test.</fo:block>
<fo:block>This is <fo:sequence
  font-style="italic">another</fo:sequence> test.</fo:block>
</fo:queue>
</fo:page-sequence>

Design Principles
In the design of any language, trade-offs in the solution space are necessary. To aid in making these trade-offs the follow design principles were used:
XSL should support browsing, printing, and interactive editing and design tools
XSL should be capable of specifying presentations for traditional and Web environments
XSL should support interaction with structured information, as well as presentation of it.
XSL should support all kinds of structured information, including both data and documents.
XSL should support both visual and non-visual presentations.
XSL should be a declarative language.
XSL should be optimized to provide simple specifications for common formatting tasks and not preclude more sophisticated formatting tasks.
XSL should provide an extensibility mechanism
The number of optional features in XSL should be kept to a minimum.
XSL should provide the formatting functionality of at least DSSSL and CSS
XSL should leverage other recommendations and standards, including XML, XLL, DOM, HTML and ECMAScript.
XSL should be expressed in XML syntax.
XSL stylesheets should be human-readable and reasonably clear.
Terseness in XSL markup is of minimal importance.

Acknowledgements
The following have contributed to authoring this draft:
Sharon Adler, Inso Corporation
Anders Berglund, Inso Corporation
Paul Grosso, ArborText
Eduardo Gutentag, Sun Microsystems
Chris Lilley, W3C
Chris Maden, O'Reilly & Associates
Jonathan Marsh, Microsoft Corporation
Henry S. Thompson, University of Edinburgh
Paul Trevithick, Bitstream
Norman Walsh, ArborText
Steve Zilles, Adobe

Changes from Previous Public Working Draft
xsl:process and xsl:process-children have been combined into xsl:apply-templates.
The expr attribute of xsl:value-of has been renamed to select.
Support for comments has been added.
Support for processing instructions has been added.
Support for text nodes has been added.
Support for result tree numbering has been added.
Support for sorting has been added.
The xsl:copy element has been added.
The xsl:element element has been added.
The xsl:attribute element has been added.
Attribute patterns have been changed: the syntax is @foo rather than attribute(foo); they can be used as match patterns and select patterns; @* can be used to match all attributes.
The argument to id() must now be quoted. Select patterns can also be used as an argument.
The syntax for patterns has been reworked; it is now more general than before.
The syntax for quoting namespaces has been changed.
Specificity has been removed.
Priorities can be real numbers.
Support for processing modes has been added.
xsl:apply-imports has been added.
define- has been removed from the name of top-level elements. xsl:attribute-set now contains xsl:attribute elements.
The default namespace (as declared with the xmlns attribute) is not used for element type names in patterns.