Internet Systems and Programming - XSL and XSLT

There are a number of reasons for transforming XML documents, including:

There are a number of XML related technologies for transformation, including the eXtensible Style Language (XSL) (Version 1.0, Recommendation, Oct 2001) and XSL Transformations (XSLT) (Version 1.0, Recommendation, Nov 1999).  The W3C provides an overview of these and related technologies at www.w3.org/Style/XSL/ and a link to a brief introduction to XSL.

The approach in XSL and XSLT is to use a declarative approach to specify transformation rules in a stylesheet.  The process of applying the stylesheet is called a transformation.  This approach can be contrasted with a programming approach which would specify the process (rather than the rules) of transformation.

XSLT is superior to Cascading Style Sheets (CSS) in that the document can be transformed and not just styled.  XSLT allows the reordering and dynamic selection of document components.  In this, XSLT provides many of the capabilities of scripting used with CSS.  However, XSLT also is more complex.  See www.w3c.org/Style for an overview of styling technologies.

Simple Example

Here is a simple example reworked from Professional XML (D. Martin, et al., Wrox Press, 2000) to transform an XML document to an HTML document.  First the original XML document "person.xml", which refers to the stylesheet "person.xsl" of type "text/xsl":

    <?xml version = "1.0" ?>
    <?xml-stylesheet type="text/xsl" href="person.xsl" ?>
    <Person age="29">
       <Name>
          <First>John</First>
          <Last>Doe</Last>
       </Name>
    </Person>

Then, the XSL stylesheet "person.xsl" using XSLT:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl" version="1.0">
    <xsl:template match = "/">
    <html><body>
    <xsl:for-each select="/Person/Name">
      <xsl:value-of select="Last"/>,
      <xsl:value-of select="First"/>
    </xsl:for-each>
    </body></html>
    </xsl:template>
    </xsl:stylesheet>

Note that the locations are specified using abbreviated XPath expressions.

When this XML file is processed, it should produce just the text "Doe", then a comma, then the text "John" bracketed in HTML and BODY elements.  Note that the elements are pulled out of the XML in a different order than they were in the original document.

XSLT

There are 37 XSLT elements.  Refer to the W3C documentation for additional details about each one.

First, the basics of building stylesheets.

The <xsl:stylsheet> element is the outer-most element of the XSLT style sheet.  It can provide the namespace and version and has other possible attributes.  The <xsl:tranform> element is a synonym.

Every stylesheet must have a template that matches the root node of the document.  There are four optional attributes: match, name, priority, and mode.  There can be multiple templates with identifying names.  For example, this named template:

    <xsl:template name='SampleTemplate'>
        <sample>
            <xsl:value-of select='/Correspondence/Name />
        </sample>
    </xsl:template>

could be invoked (e.g., with <xsl:apply-templates> or <xsl:call-template>) to produce a sample element containing the value of the selected node.  More on this later.

The <xsl:output> element specifies general information about the output.  For example, the method attribute could be "xml", "html", or "text".

Two other useful top-level elements in the stylesheet are <xsl:preserve-space> and <xsl:strip-space> which control whitespace handling.

Next, consider generating output.

The <xsl:value-of> element has already been shown.  It just yields the value of what is selected.  In addition to the select attribute, there is another attribute for disabling output escaping.

The <xsl:copy> and <xsl:copy-of> elements produce a copy of what is selected.  The <xsl:copy> element does not copy attributes or child nodes.

It also is useful to generate XML output and there are five elements for creating XML components, including <xsl:element>, <xsl:attribute>, <xsl:text>, <xsl:comment>, and <xsl:processing-instruction>.  For example, the SampleTemplate above could have used the <xsl:element>:

    <xsl:element name="Sample">
        <xsl:value-of select='/Correspondence/Name />
    </xsl:element>

Next, consider variables and parameters.

Both variables and parameters are names that may be bound to a value.  For example:

    <xsl:variable name="x" select="/Parents/Mother/@age" />

initializes the value of a variable named "x" to the age attribute of the Mother and allows:

    <xsl:value-of select="$x" />

The difference between variables and parameters is that a parameter binding provides a default value that can be overridden when the template or stylesheet is invoked.

Next, consider control structures.

XSLT element <xsl:for-each> provides iteration.  The XSLT elements <xsl:if> and <xsl:choose> support conditional testing.  There is no "else" available with <xsl:if>.  The elements <xsl:when> and <xsl:otherwise> are used with <xsl:choose:>.  For example:

    <xsl:if test="@id">
        <xsl:choose>
            <xsl:when test="@color='red'">
                ....
            </xsl:when>
            <xsl:otherwise>
                ...
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if >

Next, consider the structure of the transform specifications.

XSLT is declaration-oriented rather than command-oriented, but it is both possible and desirable to modularize the transformations much as it is desirable to modularize data and programs.  XSLT allows the modularization and naming of templates (as described) and their application via <xsl:apply-templates> and <xsl:call-template>.

The element <xsl:apply-templates> processes all children of the current node (including text nodes), unless the select attribute filters the node-set.  There is a mode attribute that allows processing in alternate order.  There are conflict-resolution rules for nodes with multiple matching templates.  The template rules can be overridden with the <xsl:apply-imports> element.  A specific named template can be applied with the <xsl:call-template>.  For example:
    <xsl:template match="/">
        <xsl:apply-templates select="Title"/>
        <xsl:call-template name="description-format"/>
    </xsl:template>
As shown in the example below, it is possible to use recursive transformations.

The <xsl:include> and <xsl:import> elements allow segmentation of XSLT into multiple files and their integration as desired.  These elements (with href attribute) must be at the top-level.  The <xsl:include> element  has the effect of including the referenced file.  The <xsl:import> element has the same effect except that the imported stylesheet definitions and template rules take precedence.

There is an extensive example in Martin et al. of converting XML to HTML with both XML file and XSLT file.  The output (produced via XMLSpy) is an HTML file.

There is also an example XSLT file that performs an XML to XML conversion.  The output is an XML file (produced via XMLSpy in UTF-16).