Skip to page content or Skip to Accesskey List.

Work

Main Page Content

Your First Xslt Page

Rated 3.8 (Ratings: 18)

Want more?

  • More articles in Code
 
Picture of teradome

Noah Mittman

Member info

User since: 08 Feb 2001

Articles written: 1

What is it?

XSLT is short for eXtensible Stylesheet Language Transformations. It's an open standard originally for turning XML documents into different XML documents. But taking it further for web authoring, you can output almost any structured document you want, like HTML, PDF or SVG, on the fly. And since you are separating content from style on an even more extreme level than HTML & CSS, you can create completely independent workflows between those who write content and those who build pages.

And it's not just a back-end, middleware solution. Mozilla/Netscape 6 and Internet Explorer both have basic XSLT support built-in. So you won't even need to install any servers to start trying it out (but you'll probably want to hold off before sending XML directly to the browser from your live sites).

Let's dive in, shall we?

So what does it look like? Let's start with a traditional Hello, World! "example.xml" document that looks like this:

<?xml version="1.0"?>

<?xml-stylesheet href="example.xsl" type="text/xsl"?>

<root>

<message>Hello, World!</message>

</root>

By adding <?xml-stylesheet href="example.xsl" type="text/xsl"?> between the XML declaration and the root element of the document, you will tell your XML parser that this page will use an XSL stylesheet.

Now here's a basic XSLT stylesheet to use for "example.xsl":

[Since XSL is XML, you'll note the requirement for declaring the XSL namespace. The use of namespaces is similar to the way modern browsers now switch between standards and quirks mode based on the DOCTYPE value in that it is a unique system identifier for what those tags mean and how to operate on them. As you can see, the XSL namespace announces that you will be using transformations as per the W3C recommendation—It won't work without it.]

<?xml version="1.0"?>

<xsl:stylesheet

version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

>

<xsl:output method="html"/>

<xsl:template match="root">

<html>

<head>

<title>XSL Test</title>

</head>

<body bgcolor="white" text="black">

<h1><xsl:apply-templates/></h1>

</body>

</html>

</xsl:template>

</xsl:stylesheet>

So what did we just make?

Putting it simply, XSL is a kind of find-and-replace script, which is executed as the XML parser walks through the document tree.

What you'll get when you view the example is a stream like this:

<html>

<head>

<title>XSL Test</title>

</head>

<body bgcolor="white" text="black">

<h1>Hello, World!</h1>

</body>

</html>

When the parser reaches the <root/> node in our example, the XSLT system will look for a match in the stylesheet and output that tag's contents. The match here is <xsl:template match="root"/>. But it could as well have been <xsl:template match="/"/>—the logic for this is based on XPath, which is the foundation for XSL (see the bottom of the article for a link to a tutorial).

You'll notice we didn't specify a match for <message/>, even though "Hello, World!" was placed inside the <h1/>. This is because of two particular concepts of XSL and XML.

Tags & Text: Picking vs Processing

The first concept is the <xsl:apply-templates/> command—it tells the parser to continue processing children nodes contained in that particular match. Without this, the XSLT system will simply output the fragment of HTML that we've created for <root/> and move on, skipping any other tags contained inside of it.

The second concept is the difference between the tag/attribute node and the text node in a document—because there was no match for <message/> when the apply-templates command was called, the tag node was skipped... but the text node itself was processed and output into the new document.

We could have asked for a behavior like this by using another xsl command called value-of. Change <xsl:apply-templates/> to <xsl:value-of select="message"/> and you get an explicit command to include the node value of <message/> (again, "Hello, World!").

So let's change our XML to look like this:

<root>

<message>Hello, World!</message>

<reply>Hey, Programming Exercise!</reply>

</root>

Now our modified stylesheet would ignore the reply value entirely, since without <xsl:apply-templates/>, the parser never walks down the document tree to the child nodes of <root/>.

If we had used the original stylesheet, it would create run-on of both elements in the same <h1/>:

<html>

<head>

<title>XSL Test</title>

</head>

<body bgcolor="white" text="black">

<h1>Hello, World!Hey, Programming Exercise!</h1>

</body>

</html>

The unmatched tag nodes are thrown out, and both text nodes are returned.

Making it flexible

Our stylesheet should then look more like this:

<?xml version="1.0"?>

<xsl:stylesheet

version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

>

<xsl:output method="html"/>

<xsl:template match="root">

<html>

<head>

<title>XSL Test</title>

</head>

<body bgcolor="white" text="black">

<xsl:apply-templates/>

</body>

</html>

</xsl:template>

<xsl:template match="message">

<h1><xsl:value-of select="."/></h1>

</xsl:template>

<xsl:template match="reply">

<p><xsl:value-of select="."/></p>

</xsl:template>

</xsl:stylesheet>

And by now, you can guess that select="." is a shortcut for the text node of the current node. This would work for a document with any number of message or reply tags in them since it doesn't pretend to know the order or number of the items—it simply specifies how they should be transformed when encountered.

Of course, there are plenty of ways to go from here, from processing tag attributes, to setting priorities when a tag fits into more than one match, to filtering based on tag or text node contents. You may not find an immediate use for XSLT, but you won't be disappointed with it's possibilities.

I highly recommend the resources and tutorials at Zvon.org for more information, especially the XSLT and XPath tutorials.

And for those looking for server-side solutions for dynamic XML publishing, you can check out the Apache group's AxKit (for Perl) and Cocoon (for Java) projects.

Noah Mittman [teradome] rode out his dot com dream at sputnik7.com for three years to the (unfortunately predictable) end, picking up a Webby Award with his colleagues along the way. He is currently applying his previous agency experience as the Senior Creative Technologist for Merkley + Partners where he spends most of his time on client-side development and advocating better user interfaces, and not updating his accessibility-oriented weblog at teradome.com

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.