The Foundation: XML, XSL, X-Link (2/4) - exploring XML
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
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,
<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: https://www.webreference.com/xml/column2/2.html
Created: Dec. 20, 1999
Revised: Dec. 21, 1999