How the XSL sheet works

This page was written in 1999.

XSL serves to 'translate' data in an XML file to HTML. In XSL I tell the browsers what HTML tags should be used to display the several data types of the XML file. For instance, I tell it that the XML element <role> should always be rendered as

name of person (role of person)

This is done by the following script

<A CLASS="person">
  <xsl:attribute name="HREF">mailto:<xsl:value-of select="person/@mail" /></xsl:attribute>
  <xsl:attribute name="TITLE">Mail <xsl:value-of select="person" /></xsl:attribute>
<xsl:value-of select="person" /></A>
(<xsl:value-of select="name" />)

wich takes as input

<role>
  <name>Project Manager</name>
  <person mail="pm@interest.co">Michel Defourny</person>
  <abbreviation>pm</abbreviation>
</role>

and gives as output

<A HREF="mailto:pm@interest.co" TITLE="Mail Michel Defourny"
  CLASS="person">Michel Defourny</A> (Project Manager)

This HTML output is further processed by the browser in the usual way of showing HTML pages. Note, however, that if you do "View Source" you see the XML file and not the generated HTML.

Making templates

In XSL you define several <xsl:templates>, each of which are meant for a part of the XML data. In this case I have defined templates for <role>, <briefing>, <task> and <reference>. These are at the end of the XSL file. For instance:

<xsl:template match="role">
  (code for displaying role information; see above)
</xsl:template>

In addition I have defined a template for "/*" and "text()" because I was advised to. I don't know what these mean.

Finally I have defined a template <xsl:template match="JDF/project">, which is the starting template that starts writing the HTML page. Because it applies to the XML root element 'JDF/project' this is the place where the XSL starts converting XML to HTML.

Reading out XML data

As you can see, the template starts with:

<xsl:template match="JDF/project">
  <HTML>

I start writing the HTML page, beginning with the style sheets, then the script that opens and closes the various tasks etc. This is just pure HTML/CSS/JavaScript. After that comes the TITLE with the first xsl statement:

<TITLE>
  Interest JDF -
  <xsl:value-of select="name" />
</TITLE>

The TITLE should be "Interest - name_of_project". To get the name of the project I read out the value of the <name> element. Since the starting point for this template is JDF/project, the XSL reads out the <name> directly under the <project> and not, for instance, the <name> of a role or a task.

So this XSL bit prints the HTML

<TITLE>Interest JDF - Develop Mechanical Component</TITLE>

and the browser faithfully prints out this title in the header of the window, as usual.

Applying templates

Then comes some more HTML that is generated in the same way. Then I want to print out the briefing. Since I have already defined a separate template for the briefing I simply call it:

<P CLASS="head">Briefing</P>
<xsl:apply-templates select="briefing" />

Now the XSL applies the template I defined for <briefing>. Next I print out the project team in an HTML unordered list. I do this by going through all <role> elements and applying the template for <role> to each of them.

<UL>
  <xsl:for-each select="role">
    <LI>
      <xsl:apply-templates select="." />
    </LI>
  </xsl:for-each>
</UL>

There's one catch: since my current context is defined by the for-each as a <role>, I cannot say <xsl:apply-templates select="role" /> because then XSL starts searching for a role element inside a role element. Instead, it should apply the template to the current context, so I say <xsl:apply-templates select="." />.

Finally I do the same for all <task> elements: go through them and apply the template.

I applied a lot of style sheets to all elements (headers, links etc.) to make the HTML look good. I wrote a little JavaScript that shows and hides the tasks. All this has nothing to do with XML or XSL: it is (D)HTML.

Conditional statements

It is also possible to print out certain data only in certain circumstances. For instance, in the example I have decided that the <report> element only appears when a report has been filled in. So if the element is not there the report should be filled in, if it is there the report should be printed out in the page.

This code takes care of that:

<P>
  <xsl:choose>
    <xsl:when test="report">
      <xsl:value-of select="report" />
    </xsl:when>
    <xsl:otherwise>
      <TEXTAREA> Fill in your report here</TEXTAREA>
    </xsl:otherwise>
  </xsl:choose>
</P>

We do an <xsl:choose> (one of the options inside the <xsl:choose> </xsl:choose> pair is chosen and executed).

Then comes the <xsl:when test="report">, which means "if <report> exists". If it exists I print out the report, if it doesn't (<xsl:otherwise>) I print out a TEXTAREA in which you can fill in the report.

All these features of XSL are very useful. Unfortunately the general usability of XSL is severely hampered by the IE5 implementation error I described on the General remarks page.