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.
Comments
Be the first to write a comment
You must me logged in to write a comment.