http://www.w3.org/TR/1998/WD-xsl-19980818
http://www.w3.org/TR/1998/WD-xsl-19980818.xml
http://www.w3.org/TR/1998/WD-xsl-19980818.html
http://www.w3.org/TR/1998/WD-xsl-19980818.pdf
Copyright © 1998 W3C (MIT, INRIA, Keio), All Rights Reserved. W3C liability, trademark, document use and software licensing rules apply.
This is a W3C Working Draft for review by W3C members and other interested parties. It is the first working draft of XSL. It is based on the XSL Submission, but differs substantially in many important respects. 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:
a language for transforming XML documents, and
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.
xsl:process-children
xsl:processXSL 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.
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 Section 2.5.1: Conflict Resolution for Template Rules.
XSL uses XML namespaces [W3C XML Names]
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 containing emphasis 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:process-children/>
</fo:page-sequence>
</xsl:template>
<xsl:template match="para">
<fo:block font-size="10pt" space-before="12pt">
<xsl:process-children/>
</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.
A stylesheet is represented by an xsl:stylesheet
element in an XML document.
XSL processors must use the XML namespaces mechanism [W3C XML Names] 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.
Issue (versioning): 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. If there is a namespace
declared as the default namespace, then an empty string may be used
as the value to specify that all result elements belong to that
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.
The xsl:stylesheet element may contain the
following types of elements:
xsl:import
xsl:include
xsl:id
xsl:strip-space
xsl:preserve-space
xsl:define-macro
xsl:define-attribute-set
xsl:define-constant
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:define-macro name="...">
...
</xsl:define-macro>
<xsl:define-attribute-set name="...">
...
</xsl:define-attribute-set>
<xsl:define-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.
Issue
(media-rule): Should we provide the functionality of CSS's
@media rule and if so how?
Ed. Note: 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.
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. 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 [W3C XML Names].
The tree contains nodes and character data. There are three kinds of node:
root nodes
element nodes
attribute nodes
Issue (node-types): We need to support at least processing instructions and comments, possibly other node types as well. Support requires having patterns that match/select them, being able to get at their contents, and being able to create them. How should this work?
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.
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 [W3C XML Names]); the URI will be null if the element type name has no prefix and there is no default namespace in scope.
An element node also has a namespace prefix map that specifies the namespace URI for each namespace prefix that is in scope for the element. The semantics of a document type may treat parts of attribute values or data content as namespace prefixes. The namespace prefix map ensures that the semantics can be preserved when the tree is written out as XML. When writing an element node out as XML, an XSL processor must add sufficient namespace-declaring attributes to the start-tag to ensure that all prefixes in the element node's namespace prefix map are correctly declared.
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 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.
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.
An element node also has an associated URI called its base URI which is used for resolving attribute values that represent relative URIs into absolute URIs. If an element occurs in an external entity, the base URI of that element is the URI of the external entity. Otherwise the base URI is the base URI of the document.
Each element node has an associated set of attribute nodes. A
defaulted attribute is treated the same as a specified attribute.
If an attribute was declared for the element type, 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 [W3C XML Names]); the URI will be null if the specified attribute name did not have a prefix. The value is the normalized value as specified by the XML Recommendation [W3C XML]. An attribute value whose value is of zero length is not treated specially.
There are no attribute nodes for attributes that declare namespaces (see [W3C XML Names]).
Issue (external-dtd): 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?
Each character within a CDATA section is treated as character
data. Thus <![CDATA[<]]> in the source
document will treated the same as <. 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 [W3C
XML].
After the tree has been constructed, but before it is otherwise processed by XSL, some whitespace characters 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 character object is preserved if any of the following apply:
The element type of the parent of the character is in the set of whitespace-preserving element types.
It is part of a chunk that contains at least one non-whitespace character. As in XML, a whitespace character is #x20, #x9, #xD or #xA. A chunk of characters is a maximal sequence of sibling characters without any intervening elements.
An ancestor element of the character 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 character object is stripped.
The xml:space attributes are not stripped from the
tree.
NOTE: This implies that if an
xml:space attribute is specified on a literal result
element, it will be included in the result.
For stylesheets, the set of whitespace-preserving element types
consists of just xsl:text.
For source documents, the set of whitespace-preserving element types is determined using the stylesheet as follows:
If the xsl:stylesheet element specifies a
default-space attribute with a value of strip,
then the set is initially empty. Otherwise the set initially
contains all element types that occur in the document.
The xsl:strip-space element causes 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.
Issue (declare-multiple-elements): Should the value of theelementattribute ofxsl:strip-space,xsl:preserve-spaceandxsl:idbe a list of element type names (and thus be renamed toelements)? If so, should theattributeattribute ofxsl:idalso be a list of attribute names?
Ed. Note: 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.
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:process-children/>
</fo:sequence>
</xsl:template>
As described later, the xsl:process-children
element recursively processes the children of the source
element.
It is possible for a source node to match more than one template rule. The template rule to be used is determined as follows:
First, all matching template rules that are less important than the most important matching template rule or rules are eliminated from consideration.
Next, all matching template rules that are less specific (as defined in Section 2.6.11: Specificity) than the most specific matching template rule or rules are eliminated from consideration.
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 an integer (positive or negative). The
default priority is 0. The integer must not be greater than
2147483647 nor less than -2147483648.
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.
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:process-children/> </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="*|/".
A pattern is a string which is matched against an element in the
source document. The most common pattern specifies the element type
name of a matching element. For example, the pattern
emph matches an element whose type is emph.
More complex patterns specify the element types of ancestors of a
matching element. For example, the pattern olist/item
matches an element whose type is item with a parent
element of type olist. Each element type in the list
of ancestors may be followed by a list of "qualifiers" separated by
commas. For example,
list[attribute(ordered)="yes")]/item[first-of-type()]
matches an element whose type is item, which is the
first amongst its siblings of this type, and which has a parent of
type list with an ordered attribute equal
to yes. This section describes the syntax and
semantics of patterns in detail.
A pattern that is matched against
an element is known as a match pattern. Patterns in
xsl:template are match patterns.
A pattern can also be used to
select a list of nodes; a pattern that is used for this is known as
a select pattern. In a select pattern, there is a current
node which provides a context for the selection. The pattern
selects the list of the source nodes that match the pattern. Nodes
in the selected list are in document
order. Patterns in xsl:process,
xsl:for-each and xsl:value-of are select
patterns.
In the following grammar, the nonterminals NCName and QName are defined in [W3C XML Names], and S is defined in [W3C XML].
Issue (pattern-text-content): Should patterns be able to match elements based on their textual content? If XSL is not to discriminate between DTDs that use attributes and those that use elements, then it needs at least a qualifier that matches an element whose pcdata content is exactly some specified string.
Issue (pattern-text-target): At the moment, the only kind of node that can match a pattern is an element. Should it be possible to have a pattern that matches text? What would this mean for the processing model?
Issue (pattern-pi-target): Should it be possible to have a pattern that matches a processing instruction?
Issue (regex): Should XSL support regular expressions for matching against any or all of pcdata content, attribute values, attribute names, element type names?
A pattern may consist of a set of patterns representing ancestry
separated by the | character. This indicates that an
element matching any one of the ancestry patterns matches the
entire pattern. Each ancestry pattern may itself have the
capability of a full pattern except for the |
operator.
This example creates an fo:sequence for either
emph or strong elements:
<xsl:template match="emph | strong">
<fo:sequence font-weight="bold">
<xsl:process-children/>
</fo:sequence>
</xsl:template>
Element ancestry can be represented within the pattern by using
the parent operator (/). This operator is based on the
familiar directory navigation metaphor. Two patterns separated by
the parent operator match an element if the right-hand side matches
the element and the left-hand side matches the parent of the
element.
| [3] | AncestryPattern | ::= | NodePatterns | |
|---|---|---|---|---|
| | (Anchor (AncestryOp NodePatterns)?) | ||||
| | (RootPattern NodePatterns?) | ||||
| [4] | NodePatterns | ::= | (ElementPatterns (AncestryOp AttributePattern)?) | |
|---|---|---|---|---|
| | AttributePattern | ||||
| [5] | ElementPatterns | ::= | ElementPattern (AncestryOp ElementPattern)* | |
|---|---|---|---|---|
| [6] | AncestryOp | ::= | '/' | '//' | |
|---|---|---|---|---|
| [7] | ElementPattern | ::= | ElementTypePattern ElementQualification? | |
|---|---|---|---|---|
For example, the following pattern matches title
source elements that have a section element as a
parent and a chapter element as a grandparent:
<xsl:template match="chapter/section/title"> ... </xsl:template>
While the parent operator specifies a parent-child relationship,
the ancestor operator (//) specifies an
ancestor-descendant relationship. Two patterns separated by the
ancestor operator match an element if the right-hand side matches
the element and the element has at least one ancestor that the
left-hand side matches. Thus zero or more levels of hierarchy may
intervene between the element matching the pattern specified on the
left-hand side of the ancestor operator and the element matching
the pattern specified on the right-hand side.
This example applies to changed elements which have
a para element as an ancestor.
<xsl:template match="para//changed"> ... </xsl:template>
The first component of an AncestryPattern can be an Anchor. An Anchor is a pattern that only a specific element in the source tree matches (if any elements at all match). The Anchor is said to address the specific element that matches it.
There are two kinds of anchor, relative and absolute. A relative anchor addresses an element relative to the current node. An absolute anchor addresses an element independently of any current node. A match pattern must not contain a RelativeAnchor; all anchors in a match pattern must be absolute. A select pattern may contain both kinds of anchor.
| [8] | Anchor | ::= | AbsoluteAnchor | |
|---|---|---|---|---|
| | RelativeAnchor | ||||
| [9] | AbsoluteAnchor | ::= | IdAnchor | |
|---|---|---|---|---|
| [10] | RelativeAnchor | ::= | CurrentNodeAnchor | |
|---|---|---|---|---|
| | (ParentAnchor ('/' ParentAnchor)*) | ||||
| | AncestorAnchor | ||||
| [11] | CurrentNodeAnchor | ::= | '.' | |
|---|---|---|---|---|
| [12] | ParentAnchor | ::= | '..' | |
|---|---|---|---|---|
A CurrentNodeAnchor addresses the current node.
A select pattern is implicitly
anchored to the current node: if an
AncestryPattern in the
Pattern does not start with an
Anchor or a
RootPattern, it is treated as if it were ./AncestryPattern. For example,
a select pattern of foo will be treated as
./foo and will thus select the foo children of
the current node.
A ParentAnchor addresses the parent of the current node.
An AncestorAnchor addresses the nearest ancestor of the current node that matches the specified pattern. The pattern in a AncestorAnchor is a match pattern.
An IdAnchor addresses the element whose ID (see Section 2.4.2.1: Unique IDs) is the specified NCName.
A RootPattern matches the root node (see Section 2.4.1: Root Node).
The simplest pattern consists of just an element type name. This matches any element of that type.
<xsl:template match="first-name"> ... </xsl:template>
The * pattern is a wildcard that matches a single
element of any type. When used within an ancestry chain, the
wildcard matches exactly one level of hierarchy.
| [16] | ElementTypePattern | ::= | OneElementTypePattern | |
|---|---|---|---|---|
| | AnyElementTypePattern | ||||
| [17] | OneElementTypePattern | ::= | ElementTypeName | |
|---|---|---|---|---|
| [18] | ElementTypeName | ::= | QName | |
|---|---|---|---|---|
| [19] | AnyElementTypePattern | ::= | '*' | |
|---|---|---|---|---|
The following pattern matches any element that is an immediate
child of a data-samples element.
<xsl:template match="data-samples/*"> ... </xsl:template>
When determining whether a source element matches an ElementTypeName, the expanded element type names are compared (see Section 2.4.2: Element Nodes).
Issue (pattern-namespace-wildcards): Should patterns of the formfoo:*or*:foobe allowed? If so, should*match any element or any element without a namespace URI?
An element within the pattern hierarchy may have qualifiers
applied to it, which further constrain which elements match the
term. These qualifiers may constrain the element to have certain
attributes or sub-elements or may constrain its position with
respect to its siblings. The qualifiers are specified in square
brackets ([]) following the element type name or
wildcard symbol. A pattern matches only if all of the qualifiers
are satisfied.
| [20] | ElementQualification | ::= | '[' Qualifiers? ']' | |
|---|---|---|---|---|
| [21] | Qualifiers | ::= | Qualifier (',' Qualifier)* | |
|---|---|---|---|---|
| [22] | Qualifier | ::= | ChildQualifier | |
|---|---|---|---|---|
| | AttributeQualifier | ||||
| | PositionalQualifier | ||||
This example matches author elements within
book elements where the book contains at least one
excerpt sub-element and the author has a degree
attribute:
<xsl:template match="book[excerpt]/author[attribute(degree)]"> ... </xsl:template>
Issue (sibling-qual): Should there be qualifiers that constrain an element to have an immediately preceding or following sibling of a particular type?
An element can be constrained to have a child element of a particular type by specifying the name of that type as a qualifier.
This example has a pattern that matches author
elements within book elements which also have
excerpt children (the author and
excerpt elements are siblings).
<xsl:template match="book[excerpt]/author"> ... </xsl:template>
NOTE: There is no requirement that each child qualifier is matched by a distinct element. Thusfoo[bar,bar]is matched by<foo><bar/></foo>.
Attributes on the source element or any of its ancestor elements can also be used to determine whether a particular rule applies to an element. An attribute qualifier constrains an element either to have a specific attribute with a specific value, or to have a specific attribute with any value.
| [24] | AttributeQualifier | ::= | AttributePattern ('=' AttributeValue)? | |
|---|---|---|---|---|
| [25] | AttributePattern | ::= | 'attribute' '(' QName ')' | |
|---|---|---|---|---|
| [26] | AttributeValue | ::= | '"' [^"]* '"' | |
|---|---|---|---|---|
| | "'" [^']* "'" | ||||
When matching attribute names, the expanded names are compared (see Section 2.4.3: Attribute Nodes).
Issue (attribute-qual-case): Do we need to be able to match attributes in a case insensitive way?
The following example matches an item element that
has for its parent a list element which has a
compact attribute:
<xsl:template match="list[attribute(compact)]/item"> ... </xsl:template>
The following example matches an item element that
has for its parent a list element whose
liststyle attribute has the value enum:
<xsl:template match="list[attribute(liststyle)='enum']/item"> ... </xsl:template>
It is also possible to select attribute nodes. Within a select pattern, an AncestryPattern can end with an AttributePattern. This will select the attribute node with the specified name for each element in the node list selected by the pattern preceding AttributePattern. Within a match pattern, an AncestryPattern must not end with an AttributePattern.
Issue (class-attribute): Should there be a way of specifying that an attribute serves as a class attribute and then pattern syntax that treats class attributes specially?
Positional qualifiers may be used to further constrain the pattern to match on the element's position or uniqueness among its siblings.
XSL defines the following positional qualifiers:
first-of-type(). The element must be the first
sibling of its type.
not-first-of-type(). The element must not be the
first sibling of its type.
last-of-type(). The element must be the last
sibling of its type.
not-last-of-type(). The element must not be the
last sibling of its type.
first-of-any(). The element must be the first
sibling element of any type.
not-first-of-any(). The element must not be the
first sibling element of any type.
last-of-any(). The element must be the last sibling
element of any type.
not-last-of-any(). The element must not be the last
sibling element of any type.
only-of-type(). The element must have no element
siblings of the same type.
not-only-of-type(). The element must have one or
more element siblings of the same type.
only-of-any(). The element must have no element
siblings at all.
not-only-of-any(). The element must have one or
more element siblings.
| [27] | PositionalQualifier | ::= | Position '(' ')' | |
|---|---|---|---|---|
| [28] | Position | ::= | 'first-of-type' | 'not-first-of-type' | |
|---|---|---|---|---|
| | 'first-of-any' | 'not-first-of-any' | ||||
| | 'last-of-type' | 'not-last-of-type' | ||||
| | 'last-of-any' | 'not-last-of-any' | ||||
| | 'only-of-type' | 'not-only-of-type' | ||||
| | 'only-of-any' | 'not-only-of-any' | ||||
The following pattern matches the first item in a
list:
<xsl:template match="list/item[first-of-type()]"> ... </xsl:template>
The following rule is used for appendix elements
when there is only one appendix:
<xsl:template match="backmatter/appendix[only-of-type()]"> ... </xsl:template>
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.
When a source element is matched against multiple patterns, it is possible for it to match more than one distinct pattern. In this situation, XSL defines which pattern or patterns are the most specific.
A pattern that starts with an IdAnchor is more specific than a pattern that does not. If two patterns both start with an IdAnchor or both do not start with an IdAnchor, then the one with the more components is the more specific, where a component is either a Qualifier or a OneElementTypePattern.
For example, the following patterns are in decreasing order of specificity:
id(employee-of-the-month)
employee[attribute(type)='contract',attribute(country)='USA']
employee[attribute(type)='contract']
employee
*
When a pattern contains alternatives separated by
|, each alternative is treated separately for specificity
purposes. A rule that contains a pattern with two alternatives is
equivalent to two rules with the same content each specifying one
of the alternatives as its patterns. For example
<xsl:template match="EMPH|B" priority="1"> <fo:sequence font-weight="bold"><xsl:process-children/></fo:sequence> </xsl:template>
is equivalent to
<xsl:template match="EMPH" priority="1"> <fo:sequence font-weight="bold"><xsl:process-children/></fo:sequence> </xsl:template> <xsl:template match="B" priority="1"> <fo:sequence font-weight="bold"><xsl:process-children/></fo:sequence> </xsl:template>
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.
Instructions can select descendant elements for processing.
There are two such instructions, the
xsl:process-children instruction and the
xsl:process instruction; the
xsl:process-children instruction processes the immediate
children of the source element, while the xsl:process
instruction processes elements 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:process-children/>
</fo:block>
<fo:rule-graphic/>
</xsl:template>
Note that xsl:process-children selects any
character children of the source element as well as the element
children. The result in this case is the sequence of results of
processing the individual character children and element children
in sequence.
Issue
(instruction-next-match): Should we add an instruction with
the functionality of next-match in DSSSL?
Issue
(instruction-error): Should there be an instruction that
generates an error, like the error procedure in
DSSSL?
Issue (instruction-sort): There needs to be an instruction that can do sorting. How should this work?
Issue (instruction-result-number): There needs to be instruction that allows result elements to be numbered. How should this work?
Issue (modes): How should the functionality of DSSSL modes be provided? Should nested template rules be used for this? Is there a way of getting source elements to appear in multiple places in the output that can be implemented in a single pass?
Issue (identity-transform): There needs to be a way to do the identity transformation (creating a result tree identical to the source tree). How should this be done?
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 attributes that were specified on the element in the template tree.
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 ({}).
The namespace prefix map of the result element node is the namespace prefix map of the element node in the stylesheet after the removal of any prefixes that map to the XSL namespace URI.
Since an XSL processor acts on elements belonging to the XSL
namespace, the problem arises of how to create elements belonging
to the XSL namespace. A namespace whose URI is
http://www.w3.org/TR/WD-xsl followed by one or more
occurrences of /quote is called a quoted namespace.
Quoted namespaces are treated specially: before a result tree is
written out as XML all quoted namespace URIs in expanded names and
in namespace prefix maps are unquoted by removing the final
/quote.
The xsl:define-attribute-set element defines a
named set of attributes. The name attribute specifies
the name of the attribute set. The content of the
xsl:define-attribute-set element is an
xsl:attribute-set element that specifies the attributes. A
literal result element or an xsl:attribute-set 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:define-attribute-set name="title-style">
<xsl:attribute-set font-size="12pt"
font-weight="bold"/>
</xsl:define-attribute-set>
<xsl:template match="chapter/heading">
<fo:block xsl:use="title-style" quadding="start">
<xsl:process-children/>
</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.
A template can also contain PCDATA. Each data character in a template remaining after whitespace has been stripped as specified in Section 2.4.5: Whitespace Stripping will create a data character in the result tree.
Literal data characters may also be wrapped in an
xsl:text element. This wrapping may change what whitespace
characters are stripped (see Section 2.4.5:
Whitespace Stripping) but does not affect how the
characters are handled by the XSL processor thereafter.
xsl:process-childrenEd. Note: There is no WG consensus on the name xsl:process-children.
Ed. Note: When we add to select patterns the ability to select characters as well as elements, the functionality of xsl:process-children will be available from xsl:process.
This example creates a block for a chapter element
and then processes its immediate children.
<xsl:template match="chapter">
<fo:block>
<xsl:process-children/>
</fo:block>
</xsl:template>
The xsl:process-children instruction processes all
of the children of the current node, including characters. However,
characters that have been stripped as specified in Section 2.4.5: Whitespace Stripping will
not be processed.
Processing a character in the source tree adds the character to
the result tree. Note that this works at the tree level. Thus,
markup of < in content will be represented by a
character < in the source tree which will, with the
built-in template rules, turn into a < character in
the result tree, which would be represented by the markup
< (or an equivalent character reference) when the
result tree is externalized as an XML document.
xsl:processEd. Note: There is no WG consensus on the name xsl:process.
Issue
(process-name): What should xsl:process be
called?
The xsl:process element processes elements selected
by a pattern. The pattern of an xsl:process element is
a select pattern and so is
implicitly anchored to the current node. The following example
processes all of the author children of the
author-group:
<xsl:template match="author-group">
<fo:sequence>
<xsl:process select="author"/>
</fo:sequence>
</xsl:template>
The xsl:process element processes all
elements which match the specified pattern. Character data
content is not matched by an xsl:process element. The
pattern must not contain an
AttributePattern except as part of an AttributeQualifier
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:process select="author/first-name"/>
</fo:sequence>
</xsl:template>
The // operator 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:process select=".//heading"/>
</fo:block>
</xsl:template>
An AncestorAnchor 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:process select="name"/> belongs to group
<xsl:process 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 AncestorAnchor 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 IdAnchor allows processing
of elements with a specific ID. For example, this template rule
applies to elements with the ID cfo; the second
xsl:process element processes the name child of
the element with ID ceo:
<xsl:template match="id(cfo)"> <xsl:process select="name"/> reports to <xsl:process select="id(ceo)/name"/> </xsl:template>
Multiple xsl:process 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:process select="sales/domestic"/>
</TABLE>
<TABLE>
<xsl:process select="sales/foreign"/>
</TABLE>
</xsl:template>
NOTE: 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:process select=".//div"/> </xsl:template>will process both the outer
divand innerdivelements.
Use of Anchors in patterns in
xsl:process 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.
Issue (select-function): What mechanisms should be provided for selecting elements for processing? For example, how can elements specified indirectly be handled? Suppose there's anxrefelement with arefattribute that specifies the ID of adivelement. The template forxrefneeds to selecttitlechild of thedivelement referenced by therefattribute. Should it be possible to select elements in other XML documents?
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.
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:process select="name"/>
</TH>
<xsl:for-each select="order">
<TD>
<xsl:process-children/>
</TD>
</xsl:for-each>
</TR>
</xsl:for-each>
</TBODY>
</TABLE>
</BODY>
</HTML>
</xsl:template>
As with xsl:process the pattern is a select pattern and so is implicitly
anchored to the current node. The select attribute is
required. The pattern must not contain an AttributePattern except as part
of an
AttributeQualifier.
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 Section 2.7.9:
Number to String Conversion Attributes 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 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 Section 2.7.9:
Number to String Conversion Attributes; 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.
The following would number the items in an ordered list:
<xsl:template match="ol/item">
<fo:block>
<xsl:number/><xsl:text>. </xsl:text><xsl:process-children/>
</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:process-children/>
</fo:block>
</xsl:template>
<xsl:template match="appendix//title">
<fo:block>
<xsl:number level="multi"
count="appendix|section|subsection"
format="A.1. "/>
<xsl:process-children/>
</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:process-children/>
</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:process-children/> </fo:block> </xsl:template>
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. The alphanumeric
tokens (format tokens) specify the format to be used for each
number in the list; the non-alphanumeric tokens (separator tokens)
specify the separators used to join numbers in the list.
Alphanumeric means any character that has a Unicode category of Nd,
Nl, No, Lu, Ll, Lt, Lm or Lo. If the first token is a separator
token, then the constructed string will start with that token; if
the last token is a separator token, then the constructed string
will end with that token. 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. The format token specifies the string to be used
to represent the number 1. If there are more than n numbers, then
the n-th number will be separated from the following number by the
separator token following the n-th format token; if there is no
such separator token, then the last separator token will be used;
if there are no separator tokens, then . will be
used.
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.
NOTE: This can be considered as specifying the language of the value of theformatattribute and hence is consistent with the semantics ofxml: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.
Ed. Note: Specify what should happen when the sequence runs out.
Here are some examples of conversion specifications:
format="ア" specifies Katakana
numbering
format="イ" specifies Katakana numbering
in the "iroha" order
format="๑" specifies numbering with Thai
digits
format="א" letter-value="other"
specifies "traditional" Hebrew numbering
format="ა" letter-value="other"
specifies Georgian numbering
format="α" letter-value="other"
specifies "classical" Greek numbering
format="а" letter-value="other"
specifies Old Slavic numbering
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.
xsl:ifThe 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:process-children/> <xsl:if test=".[not-last-of-type()]">, </xsl:if> </xsl:template>
xsl:chooseThe 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:process-children/>
</fo:list-item-body>
</fo:list-item>
</xsl:template>
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 expr
attribute. String expressions can also be used inside attribute
values of literal result elements by enclosing the string
expression in curly brace ({}).
The value of a string expression that is a pattern is the character content of the first node selected by the pattern. If the first node is an attribute node, the value is the attribute value. If the first node is an element node, the value is computed by concatenating all characters that are descendants of the element node in the order in which they occur in the document. The pattern is a select pattern and so is implicitly anchored to the current node.
Issue
(resolve-expr): 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?
xsl:value-ofThe xsl:value-of element is replaced by the value
of the string expression specified by the expr
attribute. The expr 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 expr="attribute(first-name)"/> <xsl:text> </xsl:text> <xsl:value-of expr="attribute(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 expr="first-name"/> <xsl:text> </xsl:text> <xsl:value-of expr="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 expr="ancestor(*[attribute(security)])/attribute(security)"/>
</fo:block>
<xsl:process-children/>
</xsl:template>
Issue (inherited-attribute): Unless an element counts as one of its own ancestors, usingancestor(*[attribute(security)])/attribute(security)won't work to get the inherited value of an attribute. We could either sayancestoralways includes the current node; alternatively we could provide a variant ofancestorthat does include the current node; alternatively we could provide a select pattern of the forminherited-attribute(security).
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:define-constant name="image-dir" value="/images"/>
<xsl:template match="photograph">
<IMG SRC="{constant(image-dir)}/{href}" WIDTH="{size/attribute(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 AttributeValue 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({attribute(ref)})/title}">
is not allowed.
Global string constants may be defined using a
define-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.
<xsl:define-constant name="para-font-size" value="12pt"/>
<xsl:template match="para">
<fo:block font-size="{constant(para-font-size)}">
<xsl:process-children/>
</fo:block>
</xsl:template>
Issue (local-constants): 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.
Issue (macro-name): 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:define-macro name="warning-para">
<fo:box>
<fo:block>
<xsl:text>Warning! </xsl:text>
<xsl:contents/>
</fo:block>
</fo:box>
</xsl:define-macro>
<xsl:template match="warning">
<xsl:invoke macro="warning-para">
<xsl:process-children/>
</xsl-invoke>
</xsl:template>
Macros are defined using the define-macro element.
The name attribute specifies the name of the macro
being defined. The content of the define-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.
This example defines a macro for a numbered-block
with an argument to control the format of the number.
<xsl:define-macro name="numbered-block">
<xsl:macro-arg name="format" default="1. "/>
<xsl:number format="{arg(format)}"/>
<fo:block/>
<xsl:contents/>
</fo:block>
</xsl:define-macro>
<xsl:template match="appendix/title">
<xsl:invoke name="numbered-block">
<xsl:arg name="format" value="A. "/>
<xsl:process-children/>
</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.
Issue (macro-arg-syntax): 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?
This section will describe a facility similar to style rules in the XSL submisson.
Issue (style-rules): How should style rules work?
XSL provides two mechanisms to combine stylesheets:
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 Section 2.4.2.2: Base URI).
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<xsl:import href="article.xsl"/>
<xsl:import href="bigfont.xsl"/>
<xsl:define-attribute-set name="note-style">
<xsl:attribute-set font-posture="italic"/>
</xsl:define-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.
Issue (stylesheet-partition): 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?
Issue (import-source): Provide a way for a stylesheet to import a stylesheet that is embedded in the document.
Issue (import-media): Should we provide media-dependent imports as in CSS?
Ed. Note: 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?
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 Section 2.4.2.2: Base URI). 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.
Ed. Note: What happens when a stylesheet directly or indirectly includes itself?
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:
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:
It is not in the scope of XSL to define such a mechanism.
NOTE: 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.
NOTE: 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:process-children/></fo:block> </xsl:template> </xsl:stylesheet> </head> <body> <para id="foo"> ... </para> </body> </doc>
NOTE: Thetypepseudo-attribute in thexml:stylesheetprocessing instruction identifies the stylesheet language, not the content type of the resource of which the stylesheet is a part.
This section will describe an extensibility mechanism for the tree construction process.
Issue (construct-extensibility): Should there be some extensibility mechanism for the tree construction process? If so, how should it work? Should it be language independent?
This section describes the formatting vocabulary.
The approach that we have taken in constructing this draft was to evaluate the requirements for print and online documents and established a target set of capabilities. This set of capabilities reflect the long-term goals of XSL
In this draft we concentrated on documenting a subset of the formatting capability that addressed basic WP-level pagination. We expect to cover more sophisticated pagination and support for layout-driven documents in later drafts.
The following typographic styles are used to identify different terms in this document:
property-nameThe name of a property or attribute. Always all lowercase and hyphenated between words.
property-valueThe value assigned to a property. Always all lowercase and hyphenated between words.
This has varying forms dependent on the value type:
See defined types for the definitions of character-specifier, color-specifier, length-specifier, name-specifier, writing-mode-specifier.
keywordThe name of a value for enumerated types.
0.0ptA measure (length-specifier) is always qualified with units.
0.0A numeric value (integer and fraction).
1An integer value.
Delimiters & operators, code fragments.
choice-1 | choice-2 | ... )A choice-list. Choose one of the values or options listed. These
may be mixed (such as a choice between
none and a length-specifier.
formatting-object-nameThe name of a formatting object. Always all lowercase and hyphenated between words.
Format