SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : Building Documents with XML, XSL, and CSS : Transforming with XSL

For our article, we define the XSL file to associate with our article as a processing instruction within the XML prolog:

<?xml version="1.0"?>
<?xml:stylesheet type="text/xsl" href="simple.xsl" ?>

When the article is downloaded this processing instruction is read causing the simple.xsl file to also be downloaded. Simple.xsl defines how the current document should be transformed. This approach ties together a specific XSL transformation with the document. Another approach is to dynamically bind the article with a particular XSL sheet. This can easily be done through script that loads both the XML and XSL and does the appropriate transformation. We will cover such manipulations in a future article.

XSL is an application of XML and therefore lives by XML's rules. XSL declaratively defines how to transform an XML document into another XML document. To display the document, you create your HTML document as an XML document that follows the XML rules (eg., case-sensitive tag name, closing the empty tags, etc.). The XSL is specified in your document by including the XSL namespace in the document.

A namespace is used to specify the context for the element's meaning. For example, the HTML <LI> tag is used to define a list item. However, LI in another namespace may have a different meaning. When creating an XSL sheet, you need to use the XSL namespace. Looking at simple.xls you will see that we specify the XSL namespace. This namespace is defined by the schema from the W3C web-site:

<?xml version="1.0"?>
<HTML xmlns:xsl="http://www.w3.org/TR/WD-xsl">
	...
</HTML>

The XSL is interpreted by evaluating the XSL in the page and generating a new document. We use the XSL to generate an HTML document. The new document is created by interpreting and evaluating all the XSL elements in the document. For example, in our article, we define the article's title using the title element that is specified within a meta element within the article element:

<article>
  <meta>
    <title>Sample Article Template</title>
  </meta>
</article>

When we generate the HTML page we want this title specified as the document's title. We accomplish this by extracting the value of the title element using the XSL value-of element. This element takes a path to an element and returns the requested value. The path is determined by the element's containership. The path to the title in our xml article format is: article/meta/title. Therefore to transform the article title from XML to the HTML counterpart, we write the following XSL:

<HEAD>
  <TITLE> 
    <xsl:value-of select="article/meta/title"/>
  </TITLE>
</HEAD>

This generates the HTML:

<HEAD>
  <TITLE>Sample Article Template</TITLE>
</HEAD>

Notice that all the elements in the HTML name-space are included in the new document. The elements from the XSL namespace are evaluated and returned by the XSL interpreter.

You have seen a very simple one-to-one mapping transformation of an XML element. A more common operation is to iterate over an indeterminate number of elements. This is accomplished using the XSL for-each element. This element is used to loop over the contents. We are going to use the for-each element to generate an HTML meta element to hold the document's keywords.

The keywords for the article are specified using the keyword element. Any number of keyword elements can be specified:

<article>
  <meta>
    <title>Sample Article Template</title>
    <keyword>XML</keyword>
    <keyword>XSL</keyword>
  </meta>
</article>

These keywords need to be transformed into the following HTML element:

<META NAME="keywords" VALUE="XML, XSL"/>

This transformation is different from our TITLE transformation in three ways: 1) We need to enumerate all the keywords, 2) We need to assign the contents of the KEYWORD elements to an attribute value, 3) The META element is an empty element (notice we specified the closing "/")

To assign an attribute value you use the xsl attribute element. For example, you can set the NAME attribute of the meta tag as follows:

***DOUBLECHECK***
<META/>
<xsl:attribute name="NAME">keywords</xsl:attribute>

The above is merely a demonstration. Since we are outputting a literal string a more effective approach is to set the NAME attribute directly on the META element. A more practical example is to combine the attribute, for-each, and value-of attributes to generate the value attribute:

<META NAME="keywords"/>
<xsl:attribute name="value">
 <xsl:for-each select="article/meta/keyword">
  <xsl:value-of/>, 
 </xsl:for-each>
</xsl:attribute>

Let's examine this XSL. We first generate the META tag with NAME="keywords". Next, we manipulate the META tag's value attribute. Since we want the value to be the concatenation of all the keyword values, we create a loop that enumerates all the keyword elements. We can use the value-of element by itself to output each keyword since the keyword element is already selected. Also, notice that we include a literal "," after each value. This XSL generates the following HTML:

<META NAME="keywords" VALUE="XML, XSL, "/>

Notice the trailing "," after the last keyword. We can eliminate this extra comma by using the XSL if element to test if we are at the last keyword element. The if element takes a test attribute which is used to create a conditional statement:

<META NAME="keywords"/>
<xsl:attribute name="value">
 <xsl:for-each select="article/meta/keyword">
  <xsl:value-of/>
  <xsl:if test="context()[not(end())]">, </xsl:if>
 </xsl:for-each>
</xsl:attribute>

The if element is testing whether the current element is the last element in the loop. If not the last element, we output the comma. XSL provides a complete syntax for matching and testing elements.

That almost concludes the generation of the head section of our HTML document. The last step is to include the LINK element that associates the CSS Stylesheet with the final document. As we will demonstrate, we use CSS to specify the rendering of the generated HTML. This allows us to change the rendering of the elements separately from the generation of the HTML document. Below we show you the complete XSL script for generating our document:

<HEAD>
  <TITLE> 
    <xsl:value-of select="article/meta/title"/>
  </TITLE>
  <META NAME="keywords"/>
  <xsl:attribute name="value">
   <xsl:for-each select="article/meta/keyword">
    <xsl:value-of/>
    <xsl:if test="context()[not(end())]">, </xsl:if>
   </xsl:for-each>
  </xsl:attribute>
  <LINK REL="stylesheet" TYPE="text/css" HREF="article.css"/>
</HEAD>

Next we explain how we generated the article's body content including an author mail-to link and the article's table of contents.