XSL Transformations (XSLT)

Table of contents

Introduction and context

XSLT is a language for transforming XML documents.  The result can be another XML document, an HTML document, or any text document.  The transformation is done by matching templates in an XSLT stylesheet against an XML document.  Each template defines the output produced when it is matched.  If desired, each template can use other templates recursively to produce parts of its output. 

This document summarizes the basic features of XSLT.  For more information see the W3C recommendation that defines XSLT. 

XSLT is a part of XSL, which is a general XML stylesheet language that also handles how an XML file is presented (like CSS for HTML).  XSLT is the part of XSL that deals with transformations of XML files. 

The XSLT output of the examples in this document was generated automatically using xalan

XSLT element and attribute names made from two words have a hyphen between the words (for example value-of and preserve-space).  This is in contrast to analogous XML Schema element and attribute names, in which the second word is capitalized and catenated to the first one (for example, simpleType and normalizedString). 

Some weaknesses of XSLT

Because XSLT stylesheets are XML files, and elements of XML files have to be correctly nested, it is not possible to write a stylesheet that produces the beginning of an element in one template and the end in another;  an element must be entirely written from one template. 

XSLT does not have strong facilities for modularizing a stylesheet, so complex transformations are difficult to manage.  It is easy for an XSLT stylesheet to get out of hand and become incomprehensible to its creator. 

Nodes

XML node tree

Figure 1.  Node tree for example

XSLT considers an XML file to consist of a tree of nodes, in which each element, attribute, and string of text contained in an element is a node.  Each attribute of an element is a child node of that element's node;  each child element is also a child node of that element's node.  If the element's contents are text only, the element's node has a single child node for that text;  if the element contains elements and text mixed, then its node has a child node for each segment of text and each child element.  Each node of an input XML document is processed by a template and can produce output.  The nodes are most commonly traversed in pre-order (parent node first, followed by child nodes in sequence, recursively), but XSLT provides ways of processing nodes in almost any order, as will be seen later. 

Figure 1 shows the node tree for this XML element: 

  <body>
    <p class='sum'>Total Amount: <xsl:value-of select='expense-report/total'/></p>
  </body>

Stylesheets and the stylesheet element

An XSLT stylesheet is an XML file containing a stylesheet element, as in this example: 

  <?xml version='1.0'?>
  <xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
    ...
  </xsl:stylesheet>

The xsl: prefix is commonly used for XSLT elements, but any prefix can be used if it is defined in the xmlns attribute.  Each prefix used in the stylesheet must be declared in the stylesheet element as an xmlns: attribute (as xsl: has been above, in the xmlns:xsl attribute). 

stylesheet may have an exclude-result-prefixes attribute whose value is a list of namespace prefixes that are not to be automatically given to output nodes.  Each such prefix must have been declared as an xmlns: attribute. 

Matching templates

Defining a template to match to a node

A template element can be set up to match a node pattern, as in the example below.  The pattern is given in the match attribute.  The template expression can match no nodes, one node, many nodes, or all nodes. 

  <xsl:template match='item'> <!-- Matches an item child of the context node -->
    ... <!-- See below for contents of a template -->
  </xsl:template>

See also named templates

Patterns for matching nodes

XSLT uses a subset of XPath expressions as patterns to match against XML nodes.  Expressions can be absolute (beginning with / for the root element) or relative to a context node, the current location.  Here is a list of example expressions (many adapted from examples in [XSLT] and [XPath]). 

A name may be

Localnames only match elements and attributes in an XML file with no default namespace.  Qnames only match elements and attributes whose default namespace or explicit prefix corresponds to the namespace for the qname. 

In summary:

Producing output from a template

A template element can contain text, non-XSLT elements, and XSLT elements.  When a template matches an input element or attribute, the text and non-XSLT elements it contains are written as output (with whitespace compressed or stripped and attribute value templates expanded).  XSLT elements it contains are replaced by their own output. 

Table 1.  Ways to produce output from XSLT
If you want to: Put in the template:
produce fixed output (other than XSLT elements and <!-- --> comments) the fixed output itself
produce a copy of the context node copy
compute the value of an attribute an attribute value template
compute the name of an attribute attribute
compute the name of an element, or output an XSLT element element
compute text in an element value-of
produce a set of copies of input nodes copy-of
produce a <!-- --> comment in the output comment
control output whitespace exactly and/or produce newlines in the output text

XSLT produces XML output by default (with an XML header), but can be changed to output HTML or text using the method attribute of the output element. 

See Examples 1 (copy), 2 (attribute value templates), and 3 (many ways of producing output) below for examples of templates. 

Literal template contents

The simplest way to produce text and non-XSLT elements in the output is just to put them in the contents of the template.  This always works if the text and elements are fixed and you are not particular about whitespace (see Whitespace handling). 

See Example 2 below for an example of literal contents in a template. 

copy

If a copy of the input node is desired in the output, the copy element may be used in the template.  copy creates an element or attribute with the same name as the context node (but does not create its child elements or attributes if any — see copy-of for that).  The contents of the copy element are expanded to become the contents of the output element or attribute. 

Example 1.  Copying elements and attributes
XSLT
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  <xsl:output method='xml'/>

  <xsl:template match='para'>
    <paraNest>
      <xsl:copy><xsl:apply-templates select='@*'/>Contains '<xsl:apply-templates
        select='text()'/>'.</xsl:copy>
    </paraNest>
  </xsl:template>

  <xsl:template match='@depth'>
    <xsl:copy/>
  </xsl:template>

</xsl:stylesheet>
Input
<para depth='1'>woo-woo!</para>
Output
<?xml version='1.0' encoding='UTF-8'?>
<paraNest><para depth='1'>Contains 'woo-woo!'.</para></paraNest>

Attribute value templates

Attribute values in non-XSLT elements of a template may contain attribute value templates enclosed in {}, which are expanded when output is produced for the template.  An attribute value template is an XPath expression (such as a pattern), possibly extended with XSLT variable or parameter references  ($x where x is the name of the variable or parameter) and additional functions and extensions described in [XSLT].  The context node for the attribute value template is the node matched by the template

Any pattern that can be used for matching nodes can also be used in an attribute value template: 

But there are additional XPath expressions that can be used as well, of which a few are: 

To include a { or } in an attribute, double it.  For example, {{$image-dir}} represents the literal string {$image-dir}.  Otherwise, { or } are not allowed inside the enclosing {} of an attribute value template. 

The values of certain XSL attributes such as select and name are assumed to be attribute value templates — templates in these attributes' values should not be enclosed in {}, and literal strings in these values must be quoted (with single quotes 'x' if the attribute's value is double-quoted as usual).  These attributes are listed at the end of the document in Table 3.  (They are distinguished in [XSLT]'s syntax summary of each element by having an expression type, or being enclosed in {}.)  For example:  select=''href'' selects the literal string href, while select='href' selects the child href element of the context node. 

Example 2.  Attribute value templates in a template
XSLT
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  <xsl:output method='html'/>

  <xsl:variable name='image-dir'>/images</xsl:variable>

  <xsl:template match='photograph'>
    <img src='{$image-dir}/{href}' width='{size/@width}'/>
    <xsl:text>
</xsl:text><!-- outputs a newline -->
  </xsl:template>

</xsl:stylesheet>
Input
<photograph>
  <href>headquarters.jpg</href>
  <size width='300'/>
</photograph>
Output
<img width='300' src='/images/headquarters.jpg'>

attribute

An attribute and its value can be produced in the output by an attribute element in an element child element of the template;  this allows production of an attribute with a computed name.  The attribute's name gives the output attribute's name, and the contents of the attribute element give its value. 

Unless the attribute's name is computed, or it is part of an output element produced with element, it is simpler and just as effective to put the attribute literally in the template and use an attribute value template in its value if necessary, rather than use attribute

Example:  This attribute element outputs an attribute of an img element.  The attribute's name is the value of the src-attribute variable or parameter, and the attribute's value is the contents of the context node's href child element. 

  <xsl:element name='img'>
    <xsl:attribute name='{$src-attribute}'>
      <xsl:value-of select='{href}'/>
    </xsl:attribute>
  </xsl:element>

element

An element can be produced in the output by an element element in the template;  this is used to output an element with a computed name or attribute, or to output an XSLT element.  The element's name attribute gives the output element's name, attribute child elements give the output element's attributes, and other contents of the element give the content of the output element. 

Unless the output element's name is to be computed, the output is to be an XSLT element, or the name of one of its attributes must be computed (see attribute), it is simpler and just as effective to put the element literally in the template rather than use element

Example:  This element element outputs an element whose name is the value of the photo-element variable or parameter.  The output element has a single attribute src='headquarters.jpg', and no child elements or text content. 

  <xsl:element name='{$photo-element}'>
    <xsl:attribute name='src' select='headquarters.jpg'/>
  </xsl:element>

text

Text in a template is written as output when the template matches, usually with whitespace collapsed and stripped.  However, the text contents of a text child of a template element are written unchanged.  This lets you put newlines, tabs, and strings of spaces into the output. 

text can't be used to write output elements. 

Unless the text must contain newlines or consecutive whitespace, it is simpler and just as effective to put the text literally in the template rather than use text

Example:  This text element outputs a single newline. 

  <xsl:text>
  </xsl:text>

comment

A <!-- --> comment can be produced in the output with the comment element.  The content of the comment element is used as the contents of the output comment.  Literal comments in a template are assumed to be a comment for the XSLT stylesheet, and are ignored, so a comment in the output can't be produced that way. 

Example:  This comment element outputs <!-- A comment in the output -->

  <xsl:comment> A comment in the output </xsl:comment>

Computing text with value-of

A value-of element of a template outputs text based on an attribute value template.  The expression is given as the value of the value-of element's select attribute, and is just like an ordinary attribute value template except that it is not enclosed in {}value-of lets you put the same kind of computed text in the text of an element that an attribute value template lets you put in an attribute value. 

Example:  This value-of element puts the value of the photo-element variable or parameter into the contents of an output comment. 

  <xsl:comment>photograph becomes
    <xsl:value-of select='$photo-element'/>
  </xsl:comment>

Computing nodes with copy-of

The copy-of element produces a set of copies of input nodes.  It is analogous to value-of except that its select attribute may expand to anything, rather than just to a string. 

Example of producing output from a template

This example shows the use of value-of, text, element, attribute, and comment.  (It also shows variable, which has not been discussed yet.)  Notice how whitespace is collapsed or stripped except within the text element, which is used to begin a new line in the output. 

Example 3.  Template containing value-of, text, element, attribute, comment, and variable
XSLT
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  <xsl:output method='html'/>

  <xsl:variable name='photo-element'>img</xsl:variable>
  <xsl:variable name='src-attribute'>src</xsl:variable>

  <xsl:template match='photograph'>
    <xsl:comment>photograph becomes <xsl:value-of select='$photo-element'/>
    </xsl:comment>
    <xsl:text>
</xsl:text><!-- outputs a newline -->
    <xsl:element name='{$photo-element}'>
      <xsl:attribute name='{$src-attribute}'><xsl:value-of select='href'/></xsl:attribute>
      <xsl:apply-templates select='height|width'/>
    </xsl:element>
    <xsl:text>
</xsl:text><!-- outputs a newline -->
  </xsl:template>

  <xsl:template match='height|width'><xsl:copy/></xsl:template>

  </xsl:stylesheet>
Input
<photograph width='2cm'>
  <href>headquarters.jpg</href>
</photograph>
Output
<!--photograph becomes img-->
<img src='headquarters.jpg'>

Recursively applying templates

A template element may use other templates to produce part of its output by including an apply-templates child element. 

The select attribute of apply-templates controls which templates are applied.  If select is not present, apply-templates applies templates to each of the current node's child nodes, in sequence from first to last.  If the attribute is given, its value must be an XPath expression (see the examples) that can match nodes;  then templates are applied to every node that matches the expression. 

Example:  (under construction)

Template modes

If there is more than one template that could be applied to a node, these template may each be given a different mode in order to control which one is applied.  Templates with modes also allow an input element to be processed several times with different templates, each one selected by a mode. 

The mode attribute of template and apply-templates takes a QName value ([_A-Za-z][-_:.A-Za-z0-9]*, with at most one colon).  A template with a mode attribute must also have a match attribute.  (See also named templates.) 

Which template is applied?

What if there is more than one template that could be applied? 

  1. If some of the templates have lower import precedence, they are eliminated from consideration. 
  2. If some of the templates have lower priority, they are eliminated from consideration.  Each template may be given an explicit priority by its priority attribute, whose value must be an integer (positive, negative, or zero).  Templates without a priority attribute are given a default priority that for all child element or attribute value templates is 0;  see [XSLT] for the default priority of more unusual expressions.

If more than one applicable template remains, it is an error. 

Built-in templates

XSLT processors use built-in templates that provide the most common default processing, namely to recursively apply templates to each node and to copy text through to the output.  These built-in templates are treated as though they were imported and given the lowest import precedence, so that every template provided from other sources overrides whichever built-in template might apply. 

In effect, there is no built-in processing of element nodes with no child nodes or text, or of attribute nodes, because these built-in templates do nothing for them. 

  <!-- Built-in template for element nodes -->
  <xsl:template match='*|/'>
    <xsl:apply-templates/>
  </xsl:template>
  <!-- A built-in template is imported for each mode -->
  <xsl:template match='*|/' mode='m'>
    <xsl:apply-templates mode='m'/>
  </xsl:template>
  <!-- Built-in template for text nodes -->
  <xsl:template match='text()|@*'>
    <xsl:value-of select='.'/>
  </xsl:template>

In order to prevent built-in processing of an element, define a template that matches it but does nothing, as in the example below: 

  <!-- Template that does nothing for boofle elements --->
  <xsl:template match='boofle'/>

Whitespace handling

Whitespace in input or template text is ordinarily collapsed to single spaces, and text nodes consisting only of whitespace ordinarily are stripped out before processing, so that they are not matched and result in no output.  The only exception is text elements of an XSLT file, whose whitespace is preserved by default.  The default whitespace processing for text elements and other nodes can be changed in several ways:  the xml:space attribute of input or XSLT elements;  the preserve-space element of XSLT stylesheets, which adds elements to the list of those whose whitespace is preserved;  and the strip-space element of XSLT stylesheets, which is not discussed here. 

The xml:space attribute can be given to any XML element in the input or XSLT.  Text nodes that are descendants of an element with the xml:space=preserve attribute are neither compressed nor stripped;  descendants of an element with xml:space=default are compressed and stripped.  The default is, not surprisingly, xml:space=default.  If a text node has an ancestor with xml:space=preserve and an ancestor with xml:space=default, the closest ancestor prevails. 

An XSLT stylesheet may contain preserve-space elements.  The elements attribute of preserve-space elements lists input elements whose whitespace is neither compressed nor stripped.  By default, whitespace is preserved for text elements only. 

Named templates

We have seen that a template may have a match attribute, and be applied using apply-templates.  A template may also have a name attribute and be called using call-template.  Names must be unique among templates.  call-template has a required name attribute, and calls the template with that name, regardless of its match, mode, and priority (if any). 

Variables and parameters

XSLT allows variables and parameters to be defined for stylesheets and for templates.  A variable or parameter may be given any value that an expression can return.  A second value cannot later be given to either a variable or parameter. 

A variable element defines a named value;  its name is given by its name attribute, and its value is given either by its select attribute or the element contents. 

A param element defines a named value associated with the template containing the definition.  Its name is given by its name attribute, and its default value is given either by its select attribute or the element contents. 

The final value of a parameter is set by the contents of a with-param element (if present) in call-template or apply-templates.  If the call-template or apply-templates does not contain a with-param element for a parameter, the default value set in the parameter definition is used. 

Except that parameters may be passed in, parameters and variables behave the same and are referenced in the same way:  by a $name expression in an attribute value template

Example 3.  Variables, parameters, and call-template
XSLT
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  <xsl:output method='html'/>

  <xsl:variable name='title'>Paragraph</xsl:variable>

  <xsl:template name='paragraph'>
    <xsl:param name='number'>* </xsl:param>
    <xsl:param name='numberStyle' select=''''/>
    <xsl:param name='class'/>
    <p class='{$class}' title='{$title}'>
      <span style='{$numberStyle}'><xsl:value-of select='$number'/></span>
      <xsl:value-of select='.'/>
    </p>
    <xsl:text>
</xsl:text><!-- outputs a newline -->
  </xsl:template>

  <xsl:template match='document'>
    <xsl:call-template name='paragraph'>
      <xsl:with-param name='numberStyle'>bold</xsl:with-param>
      <xsl:with-param name='class' select=''indented''/>
    </xsl:call-template>
    <!--
      Template is called with values for 'numberStyle' and 'class' parameters,
      but not for 'number', which will be given the default value
      set in the 'param' element for it.
      -->
  </xsl:template>

</xsl:stylesheet>
Input
<document>
  <paragraph number='1'>Paragraph contents.</paragraph>
</document>
Output
<p title='Paragraph' class='indented'>
<span style='bold'>* </span>
  Paragraph contents.
</p>

for-each

The for-each element selects a set of nodes and then produces output for each node in the set.  The contents of the for-each element are expanded for each selected node, using that node as the current node. 

The set of nodes is specified as a pattern in the for-each element's select attribute. 

See Example 4 for an example of its use. 

Numbering things in the output

The number element outputs a number based on the sequence of nodes in the input node tree.  Its output is controlled by a large number of attributes, of which these three are the most useful: 

Table 2.  number attributes
Attribute Effect
count A pattern matching the nodes to be counted.  If absent, the current node's name is used. 
level
  • level=single, in which case the number counts the context node's preceding siblings that also match the count pattern;  or
  • level=all, in which case the number counts all nodes that match the count pattern and precede the context node, at any level in the input tree. 
  • level=multiple, in which case the number gives an outline-style number counting all nodes that match the count pattern and precede the context node, at any level in the input tree. 
format The sequences used for numbering, and possibly (for level=multiple) the number separators (a dot is the default but can be changed). 
  • 1 indicates arabic numbering (1, 2, 3, ...). 
  • 01 indicates a leading zero up to 10 (01, 02, ... , 09, 10, ...);  001 indicates leading zeroes up to 100, etc. 
  • A indicates A, B, C, .... 
  • a indicates a, b, c, .... 
  • I indicates Roman numbering I, II, III, IV, .... 
  • i indicates Roman numbering i, ii, iii, iv, .... 
  • The interpretation of any other letters or numbers in the format value is not defined, so do not use them.  Non-alphanumeric characters are copied literally as separators. 
Example 4.  Numbering
XSLT
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  <xsl:output method='xml'/>

  <xsl:template match='/'>
    <Numbered>

      <xsl:text>
All paragraphs in the input numbered within their chapters:
</xsl:text>
      <xsl:for-each select='//paragraph'>
        <xsl:text>  </xsl:text>
        <xsl:copy><xsl:number level='single'/><xsl:text>. </xsl:text>
          <xsl:apply-templates select='text()'/></xsl:copy>
        <xsl:text>
</xsl:text>
      </xsl:for-each>

      <xsl:text>
All paragraphs in the entire input numbered in sequence:
</xsl:text>
      <xsl:for-each select='//paragraph'>
        <xsl:text>  </xsl:text>
        <xsl:copy><xsl:number level='any' format='i. '/>
          <xsl:apply-templates select='text()'/></xsl:copy>
        <xsl:text>
</xsl:text>
      </xsl:for-each>

      <xsl:text>
All paragraphs in the input outline-numbered (by chapter) in sequence:
</xsl:text>
      <xsl:for-each select='//paragraph'>
        <xsl:text>  </xsl:text>
        <xsl:copy><xsl:number level='multiple' count='chapter|paragraph'
          format='[I:a.] '/>
          <xsl:apply-templates select='text()'/></xsl:copy>
        <xsl:text>
</xsl:text>
      </xsl:for-each>

    </Numbered>
  </xsl:template>

</xsl:stylesheet>
Input
<book>
  <chapter>
    <paragraph>First.</paragraph>
    <paragraph>Second.</paragraph>
  </chapter>
  <chapter>
    <paragraph>First in second chapter.</paragraph>
  </chapter>
</book>
Output
<?xml version='1.0' encoding='UTF-8'?>
<Numbered>
All paragraphs in the input numbered within their chapters:
  <paragraph>1. First.</paragraph>
  <paragraph>2. Second.</paragraph>
  <paragraph>1. First in second chapter.</paragraph>

All paragraphs in the entire input numbered in sequence:
  <paragraph>i. First.</paragraph>
  <paragraph>ii. Second.</paragraph>
  <paragraph>iii. First in second chapter.</paragraph>

All paragraphs in the input outline-numbered (by chapter) in sequence:
  <paragraph>[I:a.] First.</paragraph>
  <paragraph>[I:b.] Second.</paragraph>
  <paragraph>[II:a.] First in second chapter.</paragraph>
</Numbered>

sort

apply-templates and for-each process the input nodes they match in the order those nodes appear in the input, unless one or more sort elements are used to specify a different order.  The sort element(s), if present, must be the first child element(s) of the apply-templates or for-each.  The sort element's select attribute is an attribute value expression that is evaluated for each node matched by the apply-templates or for-each;  the resulting value is used as a key for that input node. 

There are a variety of text functions available with which the keys may be derived from attribute values and text contents — see [XSLT] for these. 

Additional attributes of sort control how the sorting is done: 

Example 5.  Sorting
XSLT
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>
  <xsl:output method='xml'/>

  <xsl:template match='twelveDays'>
    <xsl:copy><xsl:comment> Sorted lexicographically </xsl:comment>
        <xsl:text>
</xsl:text>
      <xsl:for-each select='day'>
        <xsl:sort select='text()'/>
        <xsl:text>  </xsl:text><xsl:copy><xsl:apply-templates/></xsl:copy>
        <xsl:text>
</xsl:text>
      </xsl:for-each>
    </xsl:copy>
    <xsl:text>
</xsl:text>
  </xsl:template>

</xsl:stylesheet>
Input
<twelveDays>
  <day>A partridge in a pear tree</day>
  <day>Two turtledoves</day>
  <day>Three French hens</day>
</twelveDays>
Output
<?xml version='1.0' encoding='UTF-8'?>
<twelveDays><!-- Sorted lexicographically -->
  <day>A partridge in a pear tree</day>
  <day>Three French hens</day>
  <day>Two turtledoves</day>
</twelveDays>

If and when

There are two ways to do things conditionally in an XSLT stylesheet. 

The test attribute's value is an attribute value pattern or other XPath expression such as: 

A value of the test attribute that is not a condition is true if it is a non-zero number, non-empty string, or non-empty lists of nodes.  Zero, the empty string, and the empty node-list are all false. 

Example: 

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='1.0'>

  <xsl:template match='block'>

    <xsl:if test='@depth'><!-- if the context node has a depth attribute -->
      <xsl:value-of select='@depth'/>
    </xsl:if>

    <xsl:choose>
      <xsl:when test='0 &lt; @depth'><xsl:value-of select='@depth'/></xsl:when>
      <xsl:when test='0 = @depth'>Zero</xsl:when>
      <xsl:otherwise>Bad Depth</xsl:otherwise>
    </xsl:choose>

  </xsl:template>

</xsl:stylesheet>

Including and importing stylesheets

An include element includes another XSLT stylesheet, named by the href attribute. 

An import element includes another XSLT stylesheet, named by the href attribute, but the templates in the imported stylesheet have a lower import precedence. Import precedence affects which template is applied if more than one matches. 

(If you import a stylesheet that imports other stylesheets, see [XSLT] for its more complex but exact definition of import precedence.) 

include and import may only appear as top-level elements. 

Output method

The output element controls a number of aspects of the production of output by an XSLT processor. 

Not here, but in XSLT

See [XSLT] for a discussion of these less-needed aspects. 

  1. Processing instruction nodes, produced by your XSLT stylesheet and then processed again later. 
  2. The disable-output-escaping attribute of text and value-of
  3. strip-space, which opposes preserve-space in a non-simple manner. 
  4. sort's from, grouping-separator, grouping-size, lang, letter-value, and value attributes. 
  5. Keys. 
  6. The lang attribute, which can be important if the text being processed is not English. 
  7. Top-level parameters.  These are allowed, and are associated with the stylesheet, but XSLT provides no way to pass values in to the stylesheet so use a top-level variable instead. 

Erratum:  [XSLT] sometimes puts < or > in attribute value expressions;  you must put &lt; or &gt; instead, because attribute values cannot contain < or >

Table 3.  Attributes interpreted as XPath expressions
Element Attributes with expression value
apply-templates select
attribute name, namespace
element name, namespace
for-each select
number lang, format, letter-value, grouping-separator, grouping-size
sort select, lang, data-type, order, case-order
value-of select

References

[XPath]
XML Path Language (XPath).  W3C Recommendation. 
[XSLT]
XSL Transformations (XSLT).  W3C Recommendation. 
Valid XHTML 1.0 Strict
Valid CSS!
2010May16Su21:42
Thomas A. Alspaugh