Template Rules - Page 5
October 26, 2001
An XSLT stylesheet has a collection of template rules. Each
template rule has a pattern that identifies the source tree
nodes to which the pattern applies and a template that is added
to the result tree when the XSLT processor applies that template
rule to a matched node.
In a stylesheet document, the template rules that comprise a
stylesheet are represented as xsl:template
elements; the stylesheet above has three. The value of each
xsl:template element’s match attribute is the
pattern that gets matched against source tree nodes. The
element’s content—that is, everything between its start- and end-
tag— is the template that gets added to the result tree for each
source tree node that corresponds to the match pattern. An
xsl:template element essentially tells the XSLT
processor, "as you go through the source tree, when you find a
node of that tree whose name matches the value of my match
attribute, add my contents to the result tree."
|
Figure 1.5 The two parts of a template rule
|
For example, the first template rule in the preceding stylesheet
tells the XSLT processor what to do when it sees a year element
node as the child of another node in the source tree. (The "year"
attribute value is actually an abbreviation of "child::year.")
The template rule has one element as its template to add to the
result tree: a vintage element. This element contains an
xsl:apply-templates element that tells the processor
to apply any relevant templates to the children of the matched
element node (in this case, year). The ultimate result of this
template is the contents of the input year element surrounded by
vintage tags—in effect, renaming the source tree’s
year element to a vintage element for the result
tree. Figure 1.5 shows where the pattern and template are in one
example of a template rule.
The specialized elements in a template from the XSLT namespace
are sometimes called "instructions," because they are
instructions to the XSLT processor to add something to the
result tree. What does this make the elements in the template
that don’t use the "xsl" namespace prefix, such as the vintage
element? The stylesheet is a legal, well-formed XML document, and
the vintage element is an element in that stylesheet. Because
this element is not from the XSLT namespace, the XSLT processor
will pass it along just as it is to the result tree. In XSLT,
this is known as a "literal result element."
Like all template rules, the second xsl:template
rule in the stylesheet on page 9 tells the XSLT processor "if you
find a source tree node whose name matches the value of my match
attribute, add my contents to the result tree." The string
"price" is the pattern to match, but what are the template’s
contents? There are no contents; it’s an empty element. So, when
the XSLT processor sees a price element in the
source tree, the processor will add nothing to the result tree—in
effect, deleting the price element.
Because the stylesheet is an XML document, the template rule
would have the same effect if it were written as a single-tag
empty element, like this:
<xsl:template match="price"/>
XSLT has other ways to delete elements when copying a source tree
to a result tree, but a template rule with no template is the
simplest.
Unlike the first two template rules, the third one is not aimed
at one specific element type. It has a more complex match
pattern that uses some XPath abbreviations to make it a bit
cryptic but powerful. The pattern matches any element, attribute,
or text node, and the xsl:copy and
xsl:apply-templates elements copy any element,
attribute, or text node children of the selected nodes to the
result tree. Actually, the pattern doesn’t match any element—an
XSLT processor uses the most specific template it can find to
process each node of the source tree, so it will process any year
and price elements using the stylesheet’s templates
designed to match those specific tree nodes. Because the
processor will look for the most specific template it can find,
it doesn’t matter whether the applicable template is at the
beginning of the stylesheet or at the end—the order of the
templates in a stylesheet means nothing to an XSLT processor.
Tip: If more than one xsl:template template
rule is tied for being most appropriate for a particular source
tree node, the XSLT processor may output an error message or it
may just apply the last one to the node and
continue.
The values of all of the xsl:template elements’
match attributes are considered "patterns." Patterns
are like XPath expressions that limit you to using the child and
attribute axes, which still gives you a lot of power. (see
chapter 2, "XPath," on page 23, for more on axes and the
abbreviations used in XPath expressions and patterns.) The
"year" and "price" strings are match patterns just as much as
"*|@*|text()" is, even though they don’t take advantage of any
abbreviations or function calls.
That’s the whole stylesheet. It copies a source tree to a result
tree, deleting the price elements and renaming year elements to
vintage elements. For example, the stylesheet turns
this wine element
<wine grape="chardonnay">
<product>Carneros</product>
<year>1997</year>
<price>10.99</price>
</wine>
into this:
<?xml version="1.0" encoding="utf-8"?>
<wine grape="chardonnay">
<product>Carneros</product>
<vintage>1997</vintage>
</wine>
Although the price element was deleted, the carriage
returns before and after it were not, which is why the output has
a blank line where the price element had been in the input. This
won’t make a difference to any XML parser.
This is not an oversimplified example. Developers often use XSLT
to copy a doct with a few small changes such as the renaming
of elements or the deletion of information that shouldn’t be
available at the document’s final destination.
A Simple XSLT Stylesheet - Page 4
XSLT Quickly
Running an XSLT processor - Page 6
|