The Pattern Matcher
Let's dissect the example style sheet of my last column
to explain the three elements:
<xsl:template match="/">
This tells the XSL processor to apply the subsequent template (not shown here) when it
finds a match to the match argument, in this case the document root. The match argument needs to be specified in XPath syntax, a related W3C specification
for referencing parts of an XML document. It bears strong resemblance to directory path
specifications, with some odd additions:
<xsl:template match="shoppingcart/item">
This example matches a item tag enclosed by a shoppingcart tag, anywhere in a document tree.
<xsl:template match="/shoppingcart/item">
(Note the leading slash before shoppingcart). This example matches the same construct as
above, but only at the top level of the document, directly underneath the document root.
<xsl:template match="price[@unit='USD']">
This checks for an attribute named unit on the element price with a value
of 'USD.' It would not match a price of any other currency.
Here are some more examples, with increasing obscurity:
- * matches any element
- @* matches any attribute
- @class matches any class attribute (not any element that has a class attribute)
- chapter|appendix matches any chapter element and any appendix element
- appendix//para matches any para element with an appendix ancestor element
- text() matches any text node
- id("me") matches the element with unique ID me
- para[1] matches any para element that is the first para child element of its parent
- *[position()=1 and self::para] matches any para element that is the first child element of its parent
- para[last()=1] matches any para element that is the only para child element of its parent
- items/item[position()>1] matches any item element that has a items parent and that is not the first item child of its parent
- item[position() mod 2 = 1] would be true for any item element that is an odd-numbered item child of its parent.
- div[@class="appendix"]//p matches any p element with a div ancestor element that has a class attribute with value appendix
The rules engine
The rules engine needs to resolve conflicts when more than one pattern matches to decide
which one takes precedence. A complete discussion of precedence rules is beyond the scope
of this arcticle, but two rules of thumb are handy to remember:
- A more specific match takes precedence over a less specific one, so in case of an
item in a shoppingcart "shoppingcart/item" takes precedence over "item."
- In the case of multiple included and embedded style sheets, the latest, innermost
definition takes precedence
In practice it is a good idea to avoid conflicts altogether and stay away from overriding
rules. It is hard to debug, believe me.... Needless to say our little shopping cart
example in column 1 does not have rule conflicts of any kind.
The template processor
The template processor executes a set of instructions in consequence to a pattern match.
These instructions create new elements in the output tree, either implicitly by using
non-XSL content like
<HTML>
<HEAD>
<TITLE>Your shopping cart</TITLE>
...
or explicitly using <xsl:element>, <xsl:attribute>, or <xsl:text>.
XSL instructions like
<xsl:for-each select="shoppingcart/item">
allow you to iterate over a list of nodes, and enable selective
processing. Finally
<xsl:apply-templates>
hands over control to the pattern matcher again, to search for the next rule to be fired.
More examples and detail will follow in later installments of this column.

Produced by Michael Claßen
All Rights Reserved. Legal Notices.
URL: http://www.webreference.com/xml/column2/2.html
Created: Dec. 20, 1999
Revised: Dec. 21, 1999