Introduction to XSLT

It introduces XSLT, going through the basics of using it to transform XML on the client-side, by way of easy-to-follow tutorial examples (we have included the first three examples here). Chapter 6 of the book takes client-side XSLT to a more advanced level, and Chapters 8-11 include coverage of server-side XSLT usage.

 

This sample is taken from Chapter 5 "Introduction to XSLT"of the glasshaus title "Practical XML for the Web".

Transformation Without Change

The stylesheet has added some code to the beginning of the translated <body> element, but hasn't yet done anything with the original contents of the <body> element. That's the job of the next line, <xsl :apply-templates />. This line says "Work through all of the contents of the <body> element, and perform any other transformations you need to on any tags you find". In our next example, we'll create some more template transformations for some other elements, but for now we don't want to change anything else at all. We want the rest of the <body> element contents to be passed through unchanged.

Even though we want the content to remain unchanged, we still need to specify a transformation for the other tags in our page  < html>, <head>, <title>, <style>, <b>, <h1>, <h2>, <ul> and <li>. If we don't specify a transformation for these tags, they will be ignored, leaving us with a mass of unformatted text and no tags at all. This isn't nice. We use the Identity Transformation to pass these tags through unchanged.

The Identity Transformation is specified in those curious few lines right in the middle of headerfooter_1.xsl:

  <xsl:template match="node()|@*">

    <>xsl:copy>

      <xsl:apply-templates select="node()|@*"/>

    </xsl:copy>

  </xsl:template>

The Identity Transformation is a transformation that leaves everything just the way it found it. It matches every part of our source XML document for which we haven't given a specific rule, and passes it through unchanged  let's look at how this works now.

How Does the Identity Transformation Work?

Very often when writing a stylesheet, we find that we only want to make small changes to the input document. If this is the case, then it's easiest to pass through almost everything unchanged, and just match the few elements that need alteration.

We do this using the Identity Transformation introduced above:

<xsl:template match="node()|@*">

  <xsl:copy>

    <xsl:apply-templates select="node()|@*" />

  </xsl:copy>

</xsl :template>

This template matches both node( ) (any node in the input document) and @* (any attribute), so it matches everything. When it matches, it uses <xsl :copy> to create an identical copy of the item it has matched, and then uses <xsl:apply-templates> to process the contents of the item if there are any.

If this was the only template in a stylesheet, it would produce an output document functionally the same as the input one. The identity transformation isn't appropriate when the output document needs to be considerably different from the input document.

Normally, as we have done in Example 1 above, we would use the identity template alongside others that add, remove, or alter a few nodes. These other templates, such as the template matching <body> that we defined above, will be used rather than the identity template for the nodes that they match. Each element or attribute in the source XML document can only be matched by one template (as we'll see later in this chapter, the most specific template available is used in XSLT 1.0); this is why we had to specifically copy the <body>element to our output document rather than relying on the identity template to do it for us.

Adding the Footer

Lastly, we want to add some footer text after the unchanged <body> element contents. This is performed by the end section of our <body> element template:

  <hr/>

  Copyright 2002 DinosaurOrg.

  </body>

</xsl:template>

After the body content has been passed through unchanged, these lines add some footer HTML to the page and then close the <body> tag. We then close our body <xsl:template> element, to tell the XSLT processor we have finished dealing with the <body> element.

Finally, the last line of headerfooter _1.xsl tidies up the stylesheet with the line </xsl:stylesheet>. We're done!

Specifying Stylesheets for Different Browsers

We've already seen that you need to specify a different XSL namespace in your stylesheet depending on whether you're targeting XSLT 1.0 in the recent browsers (IE 6 and Netscape 6) or XSL-WD in IE 5.0 or IE 5.5. This might seem a major obstacle to supporting multiple browsers, since you need to change the source XML document to reference a different stylesheet depending on the browser.

In fact, the situation isn't too bad. It's possible to make sure each browser gets an appropriate stylesheet using the alternate attribute.

As with CSS, it is possible to provide both one main, and several alternative stylesheets with which to render a page. The main stylesheet is specified in the < ?xml-stylesheet ... ?> reference with alternate="no", and each of the alternative stylesheets is specified with alternate="yes". Fortunately, there is varying support for this in the different browsers, which we can exploit to provide them with different stylesheets.

Rather than the <?xml-stylesheet ... ?> reference we used in Example 1 above, we can instead use:

<?xml-stylesheet type="text/xsl" href="stylesheet_ie5.xsl" alternate="yes" ?>
<?xml-stylesheet type="text/xsl" href="stylesheet _ie6.xsl" alternate="no" ?>
<?xml-stylesheet type="text/xsl" href="stylesheet _ns6.xsl" alternate="yes" ?>


This gives us different stylesheets for the different browsers because:

·          IE 5 and IE 5.5 don't understand the alternate attribute, and will act on the first stylesheet found.

·          IE 6 does understand the alternate attribute, and will use the stylesheet that has alternate="no".

·          Netscape 6 doesn't understand the alternate attribute, and will act on the last stylesheet found.

The former two items can be trusted to work in future. The latter is a bug in Netscape that may be fixed in future, but for the moment we can exploit it to provide a different stylesheet for Netscape 6 and 7 to the one we provide for the various versions of IE.

Typically, rather than the example above, it's more useful to use:

<?xml-stylesheet type="text/xsl" href="stylesheet_ie5.xsl" alternate="yes" ?>
<?xml-stylesheet type="text/xsl" href="stylesheet _v6.xsl" alternate="no" ?>

because it's rare that you'll want to use a different stylesheet for the two version 6 browsers.

In this chapter, we'll continue to just reference one stylesheet in our XML for simplicity. When working through these examples, use the correct <xsl:stylesheet ... > tag in your XSLT stylesheets for whichever browser you use.

For browsers that support XSLT 1.0, this is:

<xsl :stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

or, for XSL-WD:

<xsl :stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

This does mean that in some cases, you'll have a lot of code shared between the XSL-WD and the XSLT 1.0 stylesheets. The best way of avoiding this is with server-side code to include the common templates in both files  using SSI, ASP, JSP, or whatever. This does still retain the benefits of client-sdie XSLT, but makes maintenance easier.

George Petrov

George PetrovGeorge Petrov is a renowned software writer and developer whose extensive skills brought numerous extensions, articles and knowledge to the DMXzone- the online community for professional Adobe Dreamweaver users. The most popular for its over high-quality Dreamweaver extensions and templates.

George is also the founder of Wappler.io - the most Advanced Web & App Builder

See All Postings From George Petrov >>

Comments

Be the first to write a comment

You must me logged in to write a comment.