Following the Rules-Based Approach to Stylesheet Development
XSL (eXtensible Stylesheet Language) has some features that may be foreign to a developer's existing programming repertoire. One of these features is the notion of templates, which are used to transform matching nodes of the XML document being processed. Learning to exploit rule-based templates early in your stylesheet career will help you to develop more maintainable code and to avoid the procedural trap.
This article compares and contrasts rule-based and procedural-based approaches to developing stylesheets to help you understand the tradeoffs. A detailed example is used to illustrate the differences. The following outline is a roadmap for how we'll come to our conclusions:
- A sample XML document to be transformed
- The desired HTML output we would like to produce
- A simple procedural stylesheet to produce the output
- A simple rule-based stylesheet to produce the output
- Comparison of the rule-based and procedural approaches
A basic understanding of XML and XSL technology will be assumed. Additional resources at the end will provide links to XSL tutorial and reference material.
Sample XML Document
For the purposes of this article, we'll define a simple XML document that we'll transform into HTML output using our procedural- and rule-based stylesheets. Here we have a simple list of customers.
<Customers> <Customer> <Name>XYZ Plumbing</Name> <City>New Haven</City> <State>CT</State> </Customer> <Customer> <Name>Joe's Bar and Grill</Name> <City>Waterbury</City> <State>CT</State> </Customer> <Customer> <Name>ABC Pizza</Name> <City>Hartford</City> <State>CT</State> </Customer> </Customers>
The Desired HTML Output
Now, let's determine what we would like the resulting output of our transformation to look like. We'll create some fairly simple HTML to display the customers sorted by name in a tabular format. To keep things simple, we'll not do any special formatting at all of our data.
<html> <body> <table> <tr> <td>Customer</td> <td>City</td> <td>State</td> </tr> <tr> <td>ABC Pizza</td> <td>Hartford</td> <td>CT</td> </tr> <tr> <td>Joe's Bar and Grill</td> <td>Waterbury</td> <td>CT</td> </tr> <tr> <td>XYZ Plumbing</td> <td>New Haven</td> <td>CT</td> </tr> </table> </body> </html>
A Procedural-Based Stylesheet
To produce the output document, we need to find a way to process a collection of
Customer nodes from our XML document and transform them into a tabular list. If you are new to XSL, you would probably try to find a looping construct and start with the
<xsl:for-each> construct. Your resulting stylesheet might look something like this:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <table> <tr> <td>Customer</td> <td>City</td> <td>State</td> </tr> <xsl:for-each select="//Customer"> <xsl:sort select="Name"/> <tr> <td><xsl:value-of select="Name"/></td> <td><xsl:value-of select="City"/></td> <td><xsl:value-of select="State"/></td> </tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet>
<xsl:template> statement in this stylesheet will begin with the root node of the document. We build the HTML according to our specification. When it comes time for looping through the
Customer nodes in our document, we use the
<xsl:for-each> statement to select the customer nodes to be processed. The
select="//Customer" attribute is an XPath expression that selects all the customer nodes in the document tree. The
<xsl:value-of> element is used to select the text values of the child