A little bit more...

Wednesday, November 15, 2006

Study XSLT Tutorial

Overview

XSL = XML Style Sheets

XSL consists of three parts:

  • XSLT - a language for transforming XML documents

  • XPath - a language for navigating in XML documents

  • XSL-FO - a language for formatting XML documents


The root element that declares the document to be an XSL style sheet is <xsl:stylesheet> or <xsl:transform>.

Note: <xsl:stylesheet> and <xsl:transform> are completely synonymous and either can be used!

More Color On The Overview
An XSLT style sheet consists of a set of template rules, each of which takes the form "if this condition is encountered in the input, then generate the following output." The order of the rules is immaterial, and there is a conflict-resolution algorithm applied when several rules match the same input. One respect in which XSLT differs from serial text processing languages, however, is that the input is not processed sequentially line by line. Rather, the input XML document is treated as a tree structure, and each template rule is applied to a node in the tree. The template rule itself can decide which nodes to process next, so the input is not necessarily scanned in its original document order. [via]

Use XSL To Transform a XML Document

First declare the a xsl document and then define templates:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>

</xsl:stylesheet>

Then specify the stylesheet in your xml source document, simply like this: <?xml-stylesheet type="text/xsl" href="cdcat.xsl"?>.

The match attribute is used to associate a template with an XML element. But match="/" defines the whole document by associating the template with the root of the xml source document, in which the value of the match attribute is an XPath expression.

In the element <xsl:for-each select="catalog/cd">, "catalog/cd" matches (case-sensitive match, after all an xsl instance is an xml document.) the data structure in the xml document, i.e., the value of the select attribute (a little bit like "select" in SQL) is an XPath expression.

We can also filter the output from the XML file by adding some criterions to the select attribute in the <xsl:for-each> element.

<xsl:for-each select="catalog/cd[artist='Bob Dylan']">

Legal filter operators are:

  • = (equal)

  • != (not equal)

  • < less than

  • > greater than
Note: 'Bob Dylan' should match exactly what is between the <artist> and </artist>, including white spaces and line breaker.

We can use an <xsl:sort> element inside the <xsl:for-each> to sort the output.

To add an if statement use the syntax below:
<xsl:if test="expression">
...
...some output if the expression is true...
...
</xsl:if>
For example:
<xsl:for-each select="catalog/cd">
<xsl:if test="price > 10">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:if>
</xsl:for-each>

See here for more conditional tests to filter the output by using <xsl:choose> and <xsl:when>.

Without its select attribute specified, <xsl:apply-templates> is used to apply any relevant template(s) to the matched node(s)'s children. While using this element's select attribute, you can be pickier about exactly which children of a node should be processed and in what order.

Referring to the xsl file directly in an xml docuemt requires that there be a XSLT aware browser.Actually, we could have alternatives for the transformation. First, we can use javascript on the client side to invoke a stand alone xml parser, such as MS XML Parser, to do the transformation. Second, we can also use server side scripting language (e.g., asp, jsp, python, etc) to do the transformation, which meets the cross browser needs.

The xsl:attribute element can be used to add attributes to result elements whether created by literal result elements in the stylesheet or by instructions such as xsl:element.

Little Tricks

1. Use <...select="@width"> to identify the attribute of an element, in which case width is the attribute name. The XPath expression ../@title selects the title attribute of the element that is the parent of the current node.

2. Use curly braces ({}) surrounding an expression to specifiy an attribute value template. e.g., <h1><a href="{../link}"><xsl:apply-templates/></a></h1> (".." may be meant to go to parent node of the current node). And see the following example for more details:
The following example creates an img result element from a photograph element in the source; the value of the src attribute of the img element is computed from the value of the image-dir variable and the string-value of the href child of the photograph element; the value of the width attribute of the img element is computed from the value of the width attribute of the size child of the photograph element:

<xsl:variable name="image-dir">/images</xsl:variable>

<xsl:template match="photograph">
<img src="{$image-dir}/{href}" width="{size/@width}"/>
</xsl:template>


With this source

<photograph>
<href>headquarters.jpg</href>
<size width="300"/>
</photograph>


the result would be

<img src="/images/headquarters.jpg" width="300"/>

3. The order in which various template rules appears in the stylesheet mean nothing to the XSLT processor.

4. The XSLT processor uses the most specific template it can find to process each node of the source tree. So template: <xsl: template match="*|@*|text()"> might do nothing if any other templates are defined, since it just matches any element, attribute and text nodes. And another example, in the existence of <xsl:template match="channel/title">, <xsl:template match="title"> might do nothing also.

Conclusion

Conceptually (the fact is almost the same most of the time), you can think of the transformation process with XSLT like this: the input xml source document is parsed as a source tree structure (DOM?), and another input, the style sheet is also parsed as a tree stucture, then it's the XSLT Processor's job to write the source tree as the result tree according to the stylesheet (mostly, template rules). Figure 1 illustrates the process.

Figure 1. Operation of an XSLT ProcessorOperation of an XSLT Processor

Resources:

1. XSLT Tutorial

2. XSL Transformations (XSLT) Version 1.0

3. 使用XML: XSLT 2.0和XQuery对比

4. What kind of language is XSLT?

5. Book: XSLT Quickly

6. Saxon: Anatomy of an XSLT processor

No comments:

About Me

My photo
I'm finishing my master degree in Software Engineering, Computer Science. I believe and have been following what Forrest Gump's Mam said: you have to do the best with what god gave you.