<xsl:number>
The <xsl:number>
element is used to
determine the position of a node in the source tree.
As such, it is useful for tasks such as numbering sections of a document and
providing a table of contents. Various attributes allow control and formatting
of the number produced.
The main control over the number produced is the level
attribute. This can have one of three values, single,
any,
or multiple.
The first of these is used to produce a number based on a node's position in
relation to its siblings, for example, to number bullet points. The second is
used to number nodes regardless of their level in the document hierarchy and
can be used, for example, to number footnotes. And the last provides a number
based on the level of a node in the hierarchy, such as you might use for
numbering sections and sub-sections in a report.
Other attributes are available to say which nodes will be
included in the numbering scheme and where in the source tree the numbering
should start. As well as providing these controls over the number associated
with a node, the <xsl:number> element provides formatting of the
numbers. For example, when we use value="multiple",
we can
specify that a section is to be numbered as 1.1.3
or A.1.3,
or even 1.A.iii
if we so desire. In fact, <xsl:number>
provides all the
flexibility in numbering and formatting of the number that we might expect from
a word processor.
When we look at the position()
function later in this
chapter, we will look again at <xsl:number>
to provide a
comparison of the possible effects.
<xsl:text>
The <xsl:text>
element is used to
put a text string into the result tree.
Isn't that what we have been doing by including the text in the stylesheet?
Well yes, but there are two circumstances where we might need more control.
The first is when we are using entity references. If we
include the text <
in our stylesheet, what do we want written to the result tree? It could be the
same text string, < or it could be the single character <.
The disable-output-escaping
attribute lets us control this. If the value of this attribute is no,
or the attribute is omitted, the result tree will contain the entity reference
(<),
but if the value is yes, the result will be the <
character. This is useful if we are, for example, outputting a text string or
code in some scripting language.
The second use of <xsl:text>
is to control
whitespace handling. Careful choice of examples
has avoided this issue so far, but now is the time to see how XSLT controls the
use of whitespace in its output. In general, a text node in the stylesheet is
copied to the result tree, as we have seen in many of our examples. For
example, we created a comma-separated list of book titles using:
<xsl:value-of select="Title"/>, <xsl:value-of
select="PubDate"/>
Here we had a text node consisting of a comma followed by a
space, and this was copied directly
to the result tree.
Frequently, we will use whitespace in our stylesheets for
formatting. For example, the code above could have been written as:
<xsl:value-of select="Title"/>,
<xsl:value-of select="PubDate"/>
In this case, the comma, any space characters that there
might be after the comma, the newline character, and the several spaces used to
indent the next line would all be output. However, since we were creating HTML
and not embedding this within a <PRE>
element, the HTML
processor (in other words the browser) will convert these to a single space.
However, what about where we do not have a character such as
a comma? The default behavior is that all text nodes that consist only of
whitespace are ignored and not
copied to the result tree. This allows us to use whitespace to format our
stylesheet without worrying about it reaching our output.
There are two ways to vary this behavior. The first is in
the XML source itself. If an ancestor element of the text node that contains
only whitespace has an xml:space
attribute with a value of preserve
(and no intervening element has an xml:space
attribute with a value of default),
then whitespace will be preserved. This can give an equivalent result to the <PRE>
element in HTML. If we want to control whitespace through the stylesheet
itself, we use <xsl:text>.
Within this element, all whitespace is preserved, even if a text node comprises
only whitespace.
While on the subject of whitespace, if you are creating an
HTML output you might be tempted to put in a non-breaking space character like
this:
<xsl:value-of
select="elem1"/> <xsl:value-of
select="elem2"/>
Unfortunately, this is not well-formed XML since
is not one of the built-in entity references in XML 1.0. (I put the version in
here, in the hope that it will be included in a later version!)
Here are three ways around that problem. The first is to use
a character reference instead:
<xsl:value-of
select="elem1"/> <xsl:value-of
select="elem2"/>
This is fine if you know you will remember what that
reference is the next time you look at the stylesheet (and you are not
expecting others to have to understand it easily).
The second is to use <xsl:text>:
<xsl:value-of
select="elem1"/>
<xsl:text> </xsl:text>
<xsl:value-of
select="elem2"/>
Again, this works, but is a bit long-winded. The third is to
put a DTD internal subset into your stylesheet to define the entity:
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " ">
]>
Now you can use
to your heart's content!