|
XSL Transformations (XSLT)
|
| [1] | Pattern | ::= | LocationPathPattern | |
| | Pattern '|' LocationPathPattern | ||||
| [2] | LocationPathPattern | ::= | '/' RelativePathPattern? | |
| | IdKeyPattern (('/' | '//') RelativePathPattern)? | ||||
| | '//'? RelativePathPattern | ||||
| [3] | IdKeyPattern | ::= | 'id' '(' Literal ')' | |
| | 'key' '(' Literal ',' Literal ')' | ||||
| [4] | RelativePathPattern | ::= | StepPattern | |
| | RelativePathPattern '/' StepPattern | ||||
| | RelativePathPattern '//' StepPattern | ||||
| [5] | StepPattern | ::= | ChildOrAttributeAxisSpecifier NodeTest Predicate* | |
| [6] | ChildOrAttributeAxisSpecifier | ::= | AbbreviatedAxisSpecifier | |
| | ('child' | 'attribute') '::' |
A pattern is defined to match a node if and only if there is possible context such that when the pattern is evaluated as an expression with that context, the node is a member of the resulting node-set. When a node is being matched, the possible contexts have a context node that is the node being matched or any ancestor of that node, and a context node list containing just the context node.
For example, p matches any p element,
because for any p if the expression p is
evaluated with the parent of the p element as context the
resulting node-set will contain that p element as one of
its members.
p element that is the
document element, since the document root is the parent of the
document element.
Although the semantics of patterns are specified indirectly in
terms of expression evaluation, it is easy to understand the meaning
of a pattern directly without thinking in terms of expression
evaluation. In a pattern, | indicates alternatives; a
pattern with one or more | separated alternatives matches
if any one of the alternative matches. A pattern that consists of a
sequence of StepPatterns separated by
/ or // is matched from right to left. The
pattern only matches if the rightmost StepPattern matches and a suitable element
matches the rest of the pattern; if the separator is /
then only the parent is a suitable element; if the separator is
//, then any ancestor is a suitable element. A StepPattern that uses the child axis matches
if the NodeTest is true for the
node and the node is not an attribute node. A StepPattern that uses the attribute axis
matches if the NodeTest is true
for the node and the node is an attribute node. When []
is present, then the first PredicateExpr in a StepPattern is evaluated with the node being
matched as the context node and the siblings of the context node that
match the NodeTest as the
context node list, unless the node being matched is an attribute node,
in which case the context node list is all the attributes that have
the same parent as the attribute being matched and that match the NameTest.
For example
appendix//ulist/item[position()=1]
matches a node if and only if all of the following are true:
the NodeTest item is
true for the node and the node is not an attribute; in other words the
node is an item element
evaluating the PredicateExpr
position()=1 with the node as context node and the
siblings of the node that are item elements as the
context node list yields true
the node has a parent that matches
appendix//ulist; this will be true if the parent is a
ulist element that has an appendix ancestor
element.
<!-- Category: top-level-element -->
<xsl:template
match = pattern
name = qname
priority = number
mode = qname>
<!-- Content: (xsl:param*, template) -->
</xsl:template>
A template rule is specified with the xsl:template
element. The match attribute is a Pattern that identifies the source node or nodes
to which the rule applies. The match attribute is
required unless the xsl:template element has a
name attribute (see [6 Named Templates]).
It is an error for the value of the match attribute to
contain a VariableReference. The
content of the xsl:template element is the template that
is instantiated when the template rule is applied.
For example, an XML document might contain:
This is an <emph>important</emph> point.
The following template rule matches emph elements and
produces a fo:inline-sequence formatting object with a
font-weight property of bold.
<xsl:template match="emph">
<fo:inline-sequence font-weight="bold">
<xsl:apply-templates/>
</fo:inline-sequence>
</xsl:template>
NOTE: Examples in this document use the fo: prefix for
the namespace http://www.w3.org/1999/XSL/Format, which is
the namespace of the formatting objects defined in [XSL].
As described next, the xsl:apply-templates element
recursively processes the children of the source element.
<!-- Category: instruction -->
<xsl:apply-templates
select = node-set-expression
mode = qname>
<!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>
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 [3.4 Whitespace Stripping]
will not be processed. If stripping of whitespace nodes has not been
enabled for an element, then all whitespace in the content of the
element will be processed as text, and thus whitespace
between child elements will count in determining the position of a
child element as returned by the position
function.
A select attribute can be used to process nodes
selected by an expression instead of processing all children. The
value of the select attribute is an expression. The expression must
evaluate to a node-set. The selected set of nodes is processed in
document order, unless a sorting specification is present (see
[10 Sorting]). The following example processes all of the
author children of the author-group:
<xsl:template match="author-group">
<fo:inline-sequence>
<xsl:apply-templates select="author"/>
</fo:inline-sequence>
</xsl:template>
The following example processes all of the given-names
of the authors that are children of
author-group:
<xsl:template match="author-group">
<fo:inline-sequence>
<xsl:apply-templates select="author/given-name"/>
</fo:inline-sequence>
</xsl:template>
This example processes all of the heading descendant
elements of the book element.
<xsl:template match="book">
<fo:block>
<xsl:apply-templates select=".//heading"/>
</fo:block>
</xsl:template>
It is also possible to process elements that are not descendants of
the current node. This example assumes that a department
element has group children and employee
descendants. It 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>
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>
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:apply-templates select=".//div"/> </xsl:template>will process both the outer
div and inner div
elements.
NOTE: Typically, xsl:apply-templates is used to
process only nodes that are descendants of the current node. Such use
of xsl:apply-templates cannot result in non-terminating
processing loops. However, when xsl:apply-templates is
used to process elements that are not descendants of the current node,
the possibility arises of non-terminating loops. For example,
<xsl:template match="foo"> <xsl:apply-templates select="."/> </xsl:template>Implementations may be able to detect such loops in some cases, but the possibility exists that a stylesheet may enter a non-terminating loop that an implementation is unable to detect. This may present a denial of service security risk.
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 have lower import precedence than the matching template rule or rules with the highest import precedence are eliminated from consideration.
Next, all matching template rules that have lower priority
than the matching template rule or rules with the highest priority are
eliminated from consideration. The priority of a template rule is
specified by the priority attribute on the template rule.
The value of this must be a real number (positive or negative),
matching the production Number
with an optional leading minus sign (-). The default
priority is computed as follows:
If the pattern contains multiple alternatives separated by
|, then it is treated equivalently to a set of template
rules, one for each alternative.
If the pattern has the form of a QName preceded by a ChildOrAttributeAxisSpecifier
or has the form
processing-instruction(Literal) preceded by a ChildOrAttributeAxisSpecifier,
then the priority is 0.
If the pattern has the form NCName:* preceded by a
ChildOrAttributeAxisSpecifier,
then the priority is -0.25.
Otherwise, if the pattern consists of just a NodeTest preceded by a ChildOrAttributeAxisSpecifier, then the priority is -0.5.
Otherwise, the priority is 0.5.
Thus, the most common kind of pattern (a pattern that tests for a node with a particular type and a particular expanded-name) has priority 0. The next less specific kind of pattern (a pattern that tests for a node with a particular type and an expanded-name with a particular namespace URI) has priority -0.25. Patterns less specific than this (patterns that just tests for nodes with particular types) have priority -0.5. Patterns more specific than the most common kind of pattern have priority 0.5.
It is an error if this leaves more than one matching template rule. An XSLT 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.
<!-- Category: instruction -->
<xsl:apply-imports />
A template rule that is being used to override a template rule in
an imported stylesheet (see [5.5 Conflict Resolution for Template Rules]) can use the
xsl:apply-imports element to invoke the overridden
template rule.
At any point in the processing of a stylesheet, there is a
current template rule. Whenever a template rule is
chosen by matching a pattern, the template rule becomes the current
template rule for the instantiation of the rule's template. When an
xsl:for-each element is instantiated, the current
template rule becomes null for the instantiation of the content of the
xsl:for-each element.
xsl:apply-imports processes the current node using
only template rules that were imported into the stylesheet element
containing the current template rule; the node is processed in the
current template rule's mode. It is an error if
xsl:apply-imports is instantiated when the current
template rule is null.
For example, suppose the stylesheet doc.xsl contains a
template rule for example elements:
<xsl:template match="example"> <pre><xsl:apply-templates/></pre> </xsl:template>
Another stylesheet could import doc.xsl and modify the
treatment of example elements as follows:
<xsl:import href="doc.xsl"/>
<xsl:template match="example">
<div style="border: solid red">
<xsl:apply-imports/>
</div>
</xsl:template>
The combined effect would be to transform an example
into an element of the form:
<div style="border: solid red"><pre>...</pre></div>
Modes allow an element to be processed multiple times, each time producing a different result.
Both xsl:template and xsl:apply-templates
have an optional mode attribute. The value of the
mode attribute is a QName, which is expanded as described
in [2.4 Qualified Names]. If xsl:template does not have
a match attribute, it must not have a mode
attribute. If an xsl:apply-templates element has a
mode attribute, then it applies only to 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 to those template
rules from xsl:template elements that do not have a
mode attribute.
There is a built-in template rule to allow recursive processing to continue in the absence of a successful pattern match by an explicit template rule in the stylesheet. This template 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>
There is also a built-in template rule for each mode, which allows
recursive processing to continue in the same mode in the absence of a
successful pattern match by an explicit template rule in the
stylesheet. This template rule applies to both element nodes and the
root node. The following shows the equivalent of the built-in
template rule for mode m.
<xsl:template match="*|/" mode="m"> <xsl:apply-templates mode="m"/> </xsl:template>
There is also a built-in template rule for text and attribute nodes that copies text through:
<xsl:template match="text()|@*"> <xsl:value-of select="."/> </xsl:template>
The built-in template rule for processing instructions and comments is to do nothing.
<xsl:template match="processing-instruction()|comment()"/>
The built-in template rule for namespace nodes is also to do nothing. There is no pattern that can match a namespace node; so, the built-in template rule is the only template rule that is applied for namespace nodes.
The built-in template rules are treated as if they were imported implicitly before the stylesheet and so have lower import precedence than all other template rules. Thus, the author can override a built-in template rule by including an explicit template rule.
<!-- Category: instruction -->
<xsl:call-template
name = qname>
<!-- Content: xsl:with-param* -->
</xsl:call-template>
Templates can be invoked by name. An xsl:template
element with a name attribute specifies a named template.
The value of the name attribute is a QName, which is expanded as described
in [2.4 Qualified Names]. If an xsl:template element has
a name attribute, it may, but need not, also have a
match attribute. An xsl:call-template
element invokes a template by name; it has a required
name attribute that identifies the template to be
invoked. Unlike xsl:apply-templates,
xsl:call-template does not change the current node or the
current node list.
The match, mode and priority attributes on an
xsl:template element do not affect whether the template
is invoked by an xsl:call-template element. Similarly,
the name attribute on an xsl:template
element does not affect whether the template is invoked by an
xsl:apply-templates element.
It is an error if a stylesheet contains more than one template with the same name and same import precedence.
This section describes instructions that directly create nodes in the result tree.
In a template, an element in the stylesheet that does not belong to the XSLT namespace and that is not an extension element (see [14.1 Extension Elements]) is instantiated to create an element node with the same expanded-name. The content of the element is a template, which is instantiated to give the content of the created element node. The created element node will have the attribute nodes that were present on the element node in the stylesheet tree, other than attributes with names in the XSLT namespace.
The created element node will also have a copy of the namespace
nodes that were present on the element node in the stylesheet tree
with the exception of any namespace node whose string-value is the
XSLT namespace URI (http://www.w3.org/1999/XSL/Transform), a
namespace URI declared as an extension namespace (see [14.1 Extension Elements]), or a namespace URI designated as an
excluded namespace. A namespace URI is designated as an excluded
namespace by using an exclude-result-prefixes attribute
on an xsl:stylesheet element or an
xsl:exclude-result-prefixes attribute on a literal result
element. The value of both these attributes is a whitespace-separated
list of namespace prefixes. The namespace bound to each of the
prefixes is designated as an excluded namespace. It is an error if
there is no namespace bound to the prefix on the element bearing the
exclude-result-prefixes or
xsl:exclude-result-prefixes attribute. The default
namespace (as declared by xmlns) may be designated as an
excluded namespace by including #default in the list of
namespace prefixes. The designation of a namespace as an excluded
namespace is effective within the subtree of the stylesheet rooted at
the element bearing the exclude-result-prefixes or
xsl:exclude-result-prefixes attribute;
a subtree rooted at an xsl:stylesheet element
does not include any stylesheets imported or included by children
of that xsl:stylesheet element.
exclude-result-prefixes attribute will avoid superfluous
namespace declarations in the result tree.
The value of an attribute of a literal result element is
interpreted as an attribute
value template: it can contain expressions contained
in curly braces ({}).
A namespace URI in the stylesheet tree that is being used to specify a namespace URI in the result tree is called a literal namespace URI. This applies to:
the namespace URI in the expanded-name of a 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 string-value of a namespace node on a literal result element in the stylesheet
<!-- Category: top-level-element -->
<xsl:namespace-alias
stylesheet-prefix = prefix | "#default"
result-prefix = prefix | "#default" />
A stylesheet can use the
xsl:namespace-alias element to declare that one namespace
URI is an alias for another namespace URI. When
a literal namespace
URI has been declared to be an alias for another namespace
URI, then the namespace URI in the result tree will be the namespace
URI that the literal namespace URI is an alias for, instead of the
literal namespace URI itself. The xsl:namespace-alias
element declares that the namespace URI bound to the prefix specified
by the stylesheet-prefix attribute is an alias for the
namespace URI bound to the prefix specified by the
result-prefix attribute. Thus, the
stylesheet-prefix attribute specifies the namespace URI
that will appear in the stylesheet, and the
result-prefix attribute specifies the corresponding
namespace URI that will appear in the result tree. The default
namespace (as declared by xmlns) may be specified by
using #default instead of a prefix. If a namespace URI
is declared to be an alias for multiple different namespace URIs, then
the declaration with the highest import precedence is used. It is
an error if there is more than one such declaration. An XSLT
processor may signal the error; if it does not signal the error, it
must recover by choosing, from amongst the declarations with the
highest import precedence, the one that occurs last in the
stylesheet.
When literal result elements are being used to create element, attribute, or namespace nodes that use the XSLT namespace URI, the stylesheet must use an alias. For example, the stylesheet
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/">
<axsl:stylesheet>
<xsl:apply-templates/>
</axsl:stylesheet>
</xsl:template>
<xsl:template match="block">
<axsl:template match="{.}">
<fo:block><axsl:apply-templates/></fo:block>
</axsl:template>
</xsl:template>
</xsl:stylesheet>
will generate an XSLT stylesheet from a document of the form:
<elements> <block>p</block> <block>h1</block> <block>h2</block> <block>h3</block> <block>h4</block> </elements>NOTE: It may be necessary also to use aliases for namespaces other than the XSLT namespace URI. For example, literal result elements belonging to a namespace dealing with digital signatures might cause XSLT stylesheets to be mishandled by general-purpose security software; using an alias for the namespace would avoid the possibility of such mishandling.
xsl:element
<!-- Category: instruction -->
<xsl:element
name = { qname }
namespace = { uri-reference }
use-attribute-sets = qnames>
<!-- Content: template -->
</xsl:element>
The xsl:element element allows an element to be
created with a computed name. The expanded-name of the
element to be created is specified by a required name
attribute and an optional namespace attribute. The
content of the xsl:element element is a template for the
attributes and children of the created element.
The name attribute is interpreted as an attribute value template.
It is an error if the string that results from instantiating the
attribute value template is not a QName. An XSLT processor may signal
the error; if it does not signal the error, then it must recover
by making the the result of instantiating the xsl:element
element be the sequence of nodes created by instantiating
the content of the xsl:element element, excluding
any initial attribute nodes. If the namespace attribute is
not present then the QName is
expanded into an expanded-name using the namespace declarations in
effect for the xsl:element element, including any default
namespace declaration.
If the namespace attribute is present, then it also is
interpreted as an attribute
value template. The string that results from instantiating
the attribute value template should be a URI reference. It is not an
error if the string is not a syntactically legal URI reference. If
the string is empty, then the expanded-name of the element has a null
namespace URI. Otherwise, the string is used as the namespace URI of
the expanded-name of the element to be created. The local part of the
QName specified by the
name attribute is used as the local part of the
expanded-name of the element to be created.
XSLT processors may make use of the prefix of the QName specified in the
name attribute when selecting the prefix used for
outputting the created element as XML; however, they are not required
to do so.
xsl:attribute
<!-- Category: instruction -->
<xsl:attribute
name = { qname }
namespace = { uri-reference }>
<!-- Content: template -->
</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 instructions such as
xsl:element. The expanded-name of the
attribute to be created is specified by a required name
attribute and an optional namespace attribute.
Instantiating an xsl:attribute element 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 name attribute is interpreted as an attribute value template.
It is an error if the string that results from instantiating the
attribute value template is not a QName or is the string
xmlns. An XSLT processor may signal the error; if it
does not signal the error, it must recover by not adding the attribute
to the result tree. If the namespace attribute is not
present, then the QName is
expanded into an expanded-name using the namespace declarations in
effect for the xsl:attribute element, not
including any default namespace declaration.
If the namespace attribute is present, then it also is
interpreted as an attribute
value template. The string that results from instantiating
it should be a URI reference. It is not an error if the string is not
a syntactically legal URI reference. If the string is empty, then the
expanded-name of the attribute has a null namespace URI. Otherwise,
the string is used as the namespace URI of the expanded-name of the
attribute to be created. The local part of the QName specified by the
name attribute is used as the local part of the
expanded-name of the attribute to be created.
XSLT processors may make use of the prefix of the QName specified in the
name attribute when selecting the prefix used for
outputting the created attribute as XML; however, they are not
required to do so and, if the prefix is xmlns, they must
not do so. Thus, although it is not an error to do:
<xsl:attribute name="xmlns:xsl" namespace="whatever"> http://www.w3.org/1999/XSL/Transform</xsl:attribute>
it will not result in a namespace declaration being output.
Adding an attribute to an element replaces any existing attribute of that element with the same expanded-name.
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.
Adding an attribute to a node that is not an element; implementations may either signal the error or ignore the attribute.
Creating nodes other than text nodes during the
instantiation of the content of the xsl:attribute
element; implementations may either signal the error or ignore the
offending nodes.
xsl:attribute contains a text node with
a newline, then the XML output must contain a character reference.
For example,
<xsl:attribute name="a">x y</xsl:attribute>will result in the output
a="x
y"(or with any equivalent character reference). The XML output cannot be
a="x y"This is because XML 1.0 requires newline characters in attribute values to be normalized into spaces but requires character references to newline characters not to be normalized. The attribute values in the data model represent the attribute value after normalization. If a newline occurring in an attribute value in the tree were output as a newline character rather than as character reference, then the attribute value in the tree created by reparsing the XML would contain a space not a newline, which would mean that the tree had not been output correctly.
<!-- Category: top-level-element -->
<xsl:attribute-set
name = qname
use-attribute-sets = qnames>
<!-- Content: xsl:attribute* -->
</xsl:attribute-set>
The xsl:attribute-set element defines a named set of
attributes. The name attribute specifies the name of the
attribute set. The value of the name attribute is a QName, which is expanded as described
in [2.4 Qualified Names]. The content of the xsl:attribute-set
element consists of zero or more xsl:attribute elements
that specify the attributes in the set.
Attribute sets are used by specifying a
use-attribute-sets attribute on xsl:element,
xsl:copy (see [7.5 Copying]) or
xsl:attribute-set elements. The value of the
use-attribute-sets attribute is a whitespace-separated
list of names of attribute sets. Each name is specified as a QName, which is expanded as described
in [2.4 Qualified Names]. Specifying a
use-attribute-sets attribute is equivalent to adding
xsl:attribute elements for each of the attributes in each
of the named attribute sets to the beginning of the content of the
element with the use-attribute-sets attribute, in the
same order in which the names of the attribute sets are specified in
the use-attribute-sets attribute. It is an error if use
of use-attribute-sets attributes on
xsl:attribute-set elements causes an attribute set to
directly or indirectly use itself.
Attribute sets can also be used by specifying an
xsl:use-attribute-sets attribute on a literal result
element. The value of the xsl:use-attribute-sets
attribute is a whitespace-separated list of names of attribute sets.
The xsl:use-attribute-sets attribute has the same effect
as the use-attribute-sets attribute on
xsl:element with the additional rule that attributes
specified on the literal result element itself are treated as if they
were specified by xsl:attribute elements before any
actual xsl:attribute elements but after any
xsl:attribute elements implied by the
xsl:use-attribute-sets attribute. Thus, for a literal
result element, attributes from attribute sets named in an
xsl:use-attribute-sets attribute will be added first, in
the order listed in the attribute; next, attributes specified on the
literal result element will be added; finally, any attributes
specified by xsl:attribute elements will be added. Since
adding an attribute to an element replaces any existing attribute of
that element with the same name, this means that attributes specified
in attribute sets can be overridden by attributes specified on the
literal result element itself.
The template within each xsl:attribute element in an
xsl:attribute-set element is instantiated each time the
attribute set is used; it is instantiated using the same current node
and current node list as is used for instantiating the element bearing
the use-attribute-sets or
xsl:use-attribute-sets attribute. However, it is the
position in the stylesheet of the xsl:attribute element
rather than of the element bearing the use-attribute-sets
or xsl:use-attribute-sets attribute that determines which
variable bindings are visible (see [11 Variables and Parameters]); thus,
only variables and parameters declared by top-level xsl:variable and
xsl:param elements are visible.
The following example creates a named attribute set
title-style and uses it in a template rule.
<xsl:template match="chapter/heading">
<fo:block quadding="start" xsl:use-attribute-sets="title-style">
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<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>
Multiple definitions of an attribute set with the same expanded-name are merged. An attribute from a definition that has higher import precedence takes precedence over an attribute from a definition that has lower import precedence. It is an error if there are two attribute sets that have the same expanded-name and equal import precedence and that both contain the same attribute, unless there is a definition of the attribute set with higher import precedence that also contains the attribute. An XSLT processor may signal the error; if it does not signal the error, it must recover by choosing from amongst the definitions that specify the attribute that have the highest import precedence the one that was specified last in the stylesheet. Where the attributes in an attribute set were specified is relevant only in merging the attributes into the attribute set; it makes no difference when the attribute set is used.
A template can also contain text nodes. Each text node in a template remaining after whitespace has been stripped as specified in [3.4 Whitespace Stripping] will create a text node with the same string-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
< 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 < (or an equivalent character
reference) when the result tree is externalized as an XML document
(unless output escaping is disabled as described in [16.4 Disabling Output Escaping]).
<!-- Category: instruction -->
<xsl:text
disable-output-escaping = "yes" | "no">
<!-- Content: #PCDATA -->
</xsl:text>
Literal data characters may also be wrapped in an
xsl:text element. This wrapping may change what
whitespace characters are stripped (see [3.4 Whitespace Stripping]) but
does not affect how the characters are handled by the XSLT processor
thereafter.
xml:lang and xml:space
attributes are not treated specially by XSLT. In particular,
it is the responsibility of the stylesheet author explicitly
to generate any xml:lang or xml:space
attributes that are needed in the result;
specifying an xml:lang or xml:space
attribute on an element in the XSLT namespace will not cause any
xml:lang or xml:space attributes to appear
in the result.
<!-- Category: instruction -->
<xsl:processing-instruction
name = { ncname }>
<!-- Content: template -->
</xsl:processing-instruction>
The xsl:processing-instruction element is instantiated
to create a processing instruction node. The content of the
xsl:processing-instruction element is a template for the
string-value of the processing instruction node. The
xsl:processing-instruction 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:processing-instruction name="xml-stylesheet">href="book.css" type="text/css"</xsl:processing-instruction>
would create the processing instruction
<?xml-stylesheet href="book.css" type="text/css"?>
It is an error if the string that results from instantiating the
name attribute is not both an NCName and a PITarget. An XSLT processor may signal
the error; if it does not signal the error, it must recover by not
adding the processing instruction to the result tree.
xsl:processing-instruction
cannot be used to output an XML declaration. The
xsl:output element should be used instead (see [16 Output]).
It is an error if instantiating the content of
xsl:processing-instruction creates nodes other than
text nodes. An XSLT 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 result of instantiating the content of the
xsl:processing-instruction contains the string
?>. An XSLT 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 a >.
<!-- Category: instruction -->
<xsl:comment>
<!-- Content: template -->
</xsl:comment>
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 string-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 nodes other than text nodes. An
XSLT 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 result of instantiating the content of the
xsl:comment contains the string -- or ends
with -. An XSLT 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
- or that ends the comment.
<!-- Category: instruction -->
<xsl:copy
use-attribute-sets = qnames>
<!-- Content: template -->
</xsl:copy>
The xsl:copy element provides an easy way of copying
the current node. Instantiating the xsl:copy element
creates a copy of the current node. The namespace nodes of the
current node are automatically copied as well, but the attributes and
children of the node are not automatically copied. The content of the
xsl:copy element is a template for the attributes and
children of the created node; the content is instantiated only for
nodes of types that can have attributes or children (i.e. root
nodes and element nodes).
The xsl:copy element may have a
use-attribute-sets attribute (see [7.1.4 Named Attribute Sets]). This is used only when copying element
nodes.
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 as follows:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
When the current node is an attribute, then if it would be an error
to use xsl:attribute to create an attribute with the same
name as the current node, then it is also an error to use
xsl:copy (see [7.1.3 Creating Attributes with xsl:attribute]).
The following example shows how xml:lang attributes
can be easily copied through from source to result. If a stylesheet
defines the following named template:
<xsl:template name="apply-templates-copy-lang"> <xsl:for-each select="@xml:lang"> <xsl:copy/> </xsl:for-each> <xsl:apply-templates/> </xsl:template>
then it can simply do
<xsl:call-template name="apply-templates-copy-lang"/>
instead of
<xsl:apply-templates/>
when it wants to copy the xml:lang attribute.
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 variable. The
xsl:value-of element does this with an expression that is specified as the
value of the select attribute. Expressions can
also be used inside attribute values of literal result elements by
enclosing the expression in curly braces ({}).
xsl:value-of
<!-- Category: instruction -->
<xsl:value-of
select = string-expression
disable-output-escaping = "yes" | "no" />
The xsl:value-of element is instantiated to create a
text node in the result tree. The required select
attribute is an expression;
this expression is evaluated and the resulting object is converted to
a string as if by a call to the string
function. The string specifies the string-value of the created text
node. If the string is empty, no text node will be created. The
created text node will be merged with any adjacent text nodes.
The xsl:copy-of element can be used to copy a node-set
over to the result tree without converting it to a string. See [11.3 Using Values of Variables and Parameters with
xsl:copy-of].
For example, the following creates an HTML paragraph from a
person element with given-name and
family-name attributes. The paragraph will contain the value
of the given-name attribute of the current node followed
by a space and the value of the family-name attribute of the
current node.
<xsl:template match="person"> <p> <xsl:value-of select="@given-name"/> <xsl:text> </xsl:text> <xsl:value-of select="@family-name"/> </p> </xsl:template>
For another example, the following creates an HTML paragraph from a
person element with given-name and
family-name children elements. The paragraph will
contain the string-value of the first given-name child
element of the current node followed by a space and the string-value
of the first family-name child element of the cu