AxKit.org [logo curtesy of http://xml.com]
--sep--
Start Navigation
About AxKit
Index
xml.apache.org
Features
Live Sites
Installation
Documentation
Daily Churn
Getting AxKit
License
Download
Mailing List
Contribute
CVS
Support
Bugs
End Navigation
Prev Top Next

XSLT

One of the most important technologies to come out of the W3C is XSLT, or, Extensible Stylesheet Language Transformations. XSLT provides a way to transform one type of XML document into another using a language written entirely in XML. XSLT works by allowing developers to create one or more template rules that are applied to the various elements in the source document to produce a second, transformed document.

While the basic concept behind XSLT is quite simple (apply these rules to the elements that match these conditions), the finer points of writing good XSLT stylesheets is a huge topic that we could never hope to cover here. We will instead provide a small example that illustrates the basic XSLT syntax.

First, though, we need to configure AxKit to transform XML documents using an XSLT processor. For this example, we will assume that you already have the Gnome XSLT library (libxml2 and libxslt, available at http://xmlsoft.org/) and its associated Perl modules installed on your server.

AxAddStyleMap text/xsl Apache::AxKit::Language::LibXSLT

Adding this line to your httpd.conf file tells AxKit to process all XML documents with a stylesheet processing instruction whose type is "text/xsl" with the LibXSLT language module.

Anatomy Of An XSLT Stylesheet

All XSLT stylesheets contain the following:

  • An XML declaration.

  • An <xsl:stylesheet> element as the document's root element.

  • A template rule that matches the root-level element of document to be processed.

Consider the following bare-bones stylesheet:

<?xml version="1.0"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">
  <xsl:template match="/">
    <!-- the content for the output document contained here -->
  </xsl:template>
</xsl:stylesheet>

Note that the root template (defined by the match="/" attribute) will be called without regard for the contents of the XML document being processed. As such, this the best place to put the top-level elements that we want to include in the output of each and every document being transformed with this stylesheet.

Template Rules And Recursion

Let's take our basic stylesheet and extend it to allow us to transform the following DocBook XML document (which we will call camelhistory.xml) into HTML:

<?xml version="1.0"?>
<book>
<title>Camels: An Historical Perspective</title>
<chapter>
  <title>Chapter One</title>
  <para>
     It was a dark and <emphasis>stormy</emphasis> night...
  </para>
</chapter>
</book>

First we need to alter the root template of our stylesheet:

<xsl:template match="/">
  <html>
    <head><xsl:copy-of select="/book/title"/></head>
    <body>
      <xsl:apply-templates/>
    </body>
  </html>
</xsl:template>

Here we have created the top-level structure of our output document and copied over the book's title element into the head element of out HTML page. The <xsl:apply-templates/> element tells the XSLT processor to pass the entire contents of the current element (in this case the <book> element, since it is the root-level element in the source document) on for further processing.

Now we need to create template rules for the other elements in the document:

<xsl:template match="chapter">
  <div class="chapter">
    <xsl:attribute name="id"><xsl:value-of 
    select="title"/></xsl:attribute>
    <xsl:apply-templates/>
  </div>
</xsl:template>
<xsl:template match="para">
  <p><xsl:apply-templates/></p>
</xsl:template>

Here we see more examples of recursive processing. The <para> and <chapter> elements are transformed into <div> and <p> elements and the contents of those elements are passed along for further processing. Note also that the XPath expressions used within the template rules are evaluated in the context of the current element. So, when we select the value of the title element to create the id attribute for the div tag, we are really saying "select the value of the title element that is a child of the current chapter element".

While this sort of recursive processing is extremely powerful, it can also be quite a performance hit and is only necessary for those cases where the current element contains other elements that need to be processed. If we know that a particular element will not contain any other elements, we need only return that element's text value.

<xsl:template match="emphasis">
  <em><xsl:value-of select="."/></em>
</xsl:template>
<xsl:template match="chapter/title">
  <h2><xsl:value-of select="."/></h2>
</xsl:template>
<xsl:template match="book/title">
  <h1><xsl:value-of select="."/></h1>
</xsl:template>
</xsl:stylesheet>

Look closely at the last two template elements. Both match a <title> element, but one defines the rule for handling titles whose parent is a book element, while the other handles the chapter titles. In fact, any valid XPath expression, XSLT function call, or combination of the two can be used to define the match rule for a template element.

Finally, we need only save our stylesheet as docbook-snippet.xsl. Once our source document is associated with this stylesheet (see the section titled Putting It Together in this appendix), if we point our browser to camelhistory.xml we will get the following output:

<?xml version="1.0"?>
<html>
  <head>
    <title>Camels: An Historical Perspective</title>
  </head>
  <body>
    <h1>Camels: An Historical Perspective</h1>
    <div class="chapter" id="Chapter One">
      <h2>Chapter One</h2>
      <p>
         It was a dark and <em>stormy</em> night...
      </p>
    </div>
  </body>
</html>

Learning More

We have only scratched the surface of how XSLT can be used to transform XML documents. For more information, see the following resources:

  • The XSLT Specification: http://www.w3.org/TR/xslt

  • Miloslav Nic's XSLT Reference: http://www.zvon.org/xxl/XSLTreference/Output/index.html

  • Jeni Tennison's XSLT FAQ: http://www.jenitennison.com/xslt/index.html

Also note that the complete set of files for the above example XSLT code is available at http://axkit.org/examples/book-xslt.tar.gz


Prev Top Next

Printer Friendly
Raw XML