Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Occasional XSLT for Experienced Software Developers

Although using XSLT to process XML is increasingly common, most developers still use it only occasionally—and often treat it as just another procedural language. But that's not the best way to use XSLT. Learn how to simplify and improve your XSLT processing using event-driven and declarative techniques.


advertisement
ML appears in some form in most modern applications—and often needs to be transformed from one form into another: merged, split, massaged, or simply reformatted into HTML. In most cases, it's far more robust and efficient to use XSLT to perform such transformations than to use common programming languages such as Java, VB.NET, or C#. But because XSLT is an add-on rather than a core language, most developers use XSLT only occasionally, and have neither time nor resources to dive into the peculiarities of XSLT development or to explore the paradigms of functional and flow-driven programming that efficient use of XSLT requires.

Such occasional use carries the danger of abusing programming techniques suitable for mainstream languages such as Java, C and Python, but that can lead to disastrous results when applied to XSLT.

However, you can avoid the problems of occasional use by studying a few applications of different well-known programming problems to an XSLT programming task through this set of simple, thoroughly explained exercises.

An XSLT processor takes an XML document as input, processes it, and outputs the content in (usually) some altered form, such as XML, HTML, or text. Here's a simple XML document that serves as the basis for the input examples in this article:



<?xml version="1.0"?> <bookstore> <book isbn="1-56592-235-2" lang="en"> <author>David Flannagan</author> <title>JavaScript: The Definitive Guide</title> </book> <book isbn="1-56592-235-1" lang="en"> <author>David Flannagan</author> <title>JavaScript: The Definitive Guide</title> </book> <book isbn="0-471-40399-7" lang="en"> <author>Dan Margulis</author> <title>Photoshop 6 for Professionals</title> </book> </bookstore>

The document describes several books in a bookstore, providing the ISBN number, a language code, author, and title for each book.

Flow-driven XSLT
Suppose you needed to extract all the book titles in the following form:

<?xml version="1.0" ?> <titles> <title>JavaScript: The Definitive Guide</title> <title>JavaScript: The Definitive Guide</title> <title>Photoshop 6 for Professionals</title> </titles>

A flow-driven XSLT stylesheet example might look like this:



<?xml version="1.0" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="/bookstore"> <titles> <xsl:for-each select="book"> <xsl:call-template name="process-book"/> </xsl:for-each> </titles> </xsl:template> <xsl:template name="process-book"> <xsl:copy-of select="title"/> </xsl:template> </xsl:stylesheet>

The stylesheet matches the root node right away (<xsl:template match="/bookstore">), and then enforces the control flow afterwards by pointing to each <book> node using the combination of the for-each construct and the call-template function.

The example above is somewhat incomplete as it does not give exactly the same output as the one defined in the problem definition. Indeed, once you launch it, the result is one long line resembling this:

<?xml version="1.0"?> <titles><title>JavaScript: The Definitive Guide</title> <title>JavaScript: The Definitive Guide</title><title >Photoshop 6 for Professionals</title></titles>

To format it nicely, you have to add one more statement to the XSLT stylesheet:

<xsl:output indent="yes" encoding="utf-8"/>

The indent="yes" activates the indentation. It is also wise to specify an output encoding explicitly, even though UTF-8 is the default encoding for XSLT.

Now, suppose you make the input file a bit more complex, introducing sections and rows to locate books more easily in the bookstore:

<?xml version="1.0"?> <bookstore> <section num="1"> <row num="1"> <book isbn="1-56592-235-2" lang="en"> <author>David Flannagan</author> <title>JavaScript: The Definitive Guide</title> </book> <book isbn="1-56592-235-1" lang="en"> <author>David Flannagan</author> <title>JavaScript: The Definitive Guide</title> </book> <book isbn="0-471-40399-7" lang="en"> <author>Dan Margulis</author> <title>Photoshop 6 for Professionals</title> </book> </row> </section> </bookstore>

If you try to continue in the flow-driven way, the XSLT must grow considerably (and as you'll see, needlessly) to adapt to the format change, adding templates to iterate over and process the <section> and <row> elements:

<?xml version="1.0" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output indent="yes" encoding="utf-8"/> <xsl:template match="/bookstore"> <titles> <xsl:for-each select="section"> <xsl:call-template name="process-section"/> </xsl:for-each> </titles> </xsl:template> <xsl:template name="process-section"> <xsl:for-each select="row"> <xsl:call-template name="process-row"/> </xsl:for-each> </xsl:template> <xsl:template name="process-row"> <xsl:for-each select="book"> <xsl:call-template name="process-book"/> </xsl:for-each> </xsl:template> <xsl:template name="process-book"> <xsl:copy-of select="title"/> </xsl:template> </xsl:stylesheet>




Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap