1.4 Summary
This chapter has given you a little taste of XSLT—how it works and a few things you can do with it. After reading this introduction, you should understand the ground rules of XSLT stylesheets and the steps involved in transforming documents with a browser, a command-line processor like Xalan, or a processor with a graphical interface, such as xRay2. In the
|
Chapter 2. Building New Documents with XSLTIn the first chapter of this book, you got acquainted with the basics of how XSLT works. This chapter will take you a few steps further by showing you how to add text and markup to your result tree with XSLT templates. First, you'll add literal text to your output. Then you'll work with literal result elements , that is, elements that are represented literally in templates. You'll also learn how to add content with the text , element , attribute , attribute-set , comment , and processing-instruction elements. In addition, you'll get your first encounter with attribute value templates, which provide a way to define templates inside attribute values. |
2.1 Outputting Text
You can put plain, literal text into an XSLT template, and it will be written to a result tree when the template containing the text is
Look at the single-element document text.xml in examples/ch02 (this directory is where all example files mentioned in this chapter can be found): <?xml version="1.0"?> <message>You can easily add text to your output.</message> With text.xml in mind, consider the stylesheet txt.xsl :
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="text"/>
<template match="/">Message: <apply-templates/></template>
</stylesheet>
When applied to
text.xml
, here is what
Apply txt.xsl to text.xml using Xalan: xalan text.xml txt.xsl This gives you the following output: Message: You can easily add text to your output.
The
txt.xsl
stylesheet
2.1.1 Using the text ElementInstead of literal text, you can use XSLT's text instruction element to write text to a result tree. Instruction elements, you'll remember, are elements that are legal only inside templates. Using the text element gives you more control over result text than literal text can. The template rule in lf.xsl contains some literal text, including whitespace: <stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform"> <output method="text"/> <template match="/">Message: <apply-templates/> </template> </stylesheet> When you apply lf.xsl to text.xml with Xalan like this: xalan text.xml lf.xsl
the whitespace—a
Message: You can easily add text to your output. The XSLT processor sees the whitespace in the stylesheet as literal text and outputs it as such. The XSLT instruction element text allows you to take control over the whitespace that appears in your template. In contrast, the stylesheet text.xsl uses the text instruction element:
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="text"/>
<template match="/">
<text>Message: </text>
<apply-templates/>
</template>
</stylesheet>
When you insert text like this, the only whitespace that is preserved is what is contained in the text element—a single space. Try it to see what happens: xalan text.xml text.xsl This gives you the same output you got with txt.xsl , with no hidden whitespace: Message: You can easily add text to your output. Back in the stylesheet txt.xsl , recall how things are laid out in the template element: <template match="/">Message: <apply-templates/></template>
The literal text "Message: " comes immediately after the
template
start tag. The reason is that if you use any literal text that is not whitespace in a template, an XSLT processor interprets adjacent whitespace in the
template
element as significant. Any whitespace that is
To see more of how whitespace effects literal text in a result, look at the stylesheet whitespace.xsl :
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="text"/>
<template match="/">
Message:
<apply-templates/>
...including whitespace!
</template>
</stylesheet>
Now, process it against text.xml to see what happens: xalan text.xml whitespace.xsl Observe how the whitespace is preserved, both from above and below the apply-templates element:
Message:
You can easily add text to your output.
...including whitespace!
If no nonwhitespace literal text
Whitespace is obviously hard to see. I recommend that you make a copy of whitespace.xsl and experiment with whitespace to see what happens when you process it.
If you use text elements, the other whitespace within template elements becomes insignificant and is discarded when processed. You'll find that whitespace is easier to control if you use text elements. The control.xsl stylesheet uses text elements to handle the whitespace in its template:
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="text"/>
<template match="/">
<text>Message: </text>
<text>
</text>
<text>
</text>
<apply-templates/>
<text>
...and whitespace, too!</text>
</template>
</stylesheet>
The
control.xsl
stylesheet has four
text
elements, two of which contain only whitespace, including one that
xalan text.xml control.xsl As an alternative, you could also insert line breaks by using character references , like this: <text> </text>
This instance of the
text
element contains character references to two line breaks in succession. A character reference begins with an ampersand (
&
) and ends with a semicolon (
;
). In XML, you can use decimal or hexadecimal character references. The decimal character reference
represents the linefeed character using the decimal number 10, preceded by a
2.1.1.1 The
|
|
Character |
Entity reference |
Numeric character reference |
|---|---|---|
|
< (less-than) |
< |
< |
|
& (ampersand) |
& |
& |
|
> (greater-than) |
> |
> |
|
" (quotation) |
" |
" |
|
' (apostrophe) |
' |
' |
The greater-than entity is provided so that XML can be compatible with Standard Generalized Markup Language (SGML). The > character alone is permissible in character data and in attribute values, escaped or not. (For SGML compatibility, you always need to escape the > character if it appears as part of the sequence ]]> , which is used to end CDATA sections. CDATA sections are described in more detail in Chapter 3.)
|
The
"
and
'
entities allow you to include double and single quotes in attribute values. A second matching quote should
You have to escape an ampersand in character content because the ampersand itself is used to escape characters in entity and character references! If that's confusing, a few examples should clear things up. I'll now show you how the disable-output-escaping attribute works.
The little document
escape.xml
contains the
<title>O'Reilly</title>
The stylesheet noescape.xsl adds some new text to this title using the default, which is to not disable output escaping:
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="xml" omit-xml-declaration="yes"/>
<template match="/">
<publisher xmlns="">
<value-of select="title" xmlns="http://www.w3.org/1999/XSL/Transform"/>
<text disable-output-escaping="no" xmlns="http://www.w3.org/1999/XSL/Transform"> & Associates</text>
</publisher>
</template>
</stylesheet>
noescape.xsl
uses the
xml
output method. You can't see the effect of output escaping when the output method is
text
, so you have to use either the
xml
or
html
methods. You'll learn more about output
This stylesheet also redeclares the XSLT namespace several times (on the value-of and text elements). You'll see how to circumvent this cumbersome practice with a namespace prefix in "Adding a Namespace Prefix," later in this chapter.
To see output escaping in action, process escape.xml with this command:
xalan escape.xml noescape.xsl
Here is the result:
<publisher>O'Reilly & Associates</publisher>
disable-output-escaping with a value of no has the same effect as having no attribute at all, that is, the output is escaped and & is preserved in the result.
The following stylesheet, escape.xsl , disables output escaping:
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="xml" omit-xml-declaration="yes"/>
<template match="/">
<publisher xmlns="">
<value-of select="title" xmlns="http://www.w3.org/1999/XSL/Transform"/>
<text disable-output-escaping="yes" xmlns="http://www.w3.org/1999/XSL/Transform"> & Associates</text>
</publisher>
</template>
</stylesheet>
Process this:
xalan escape.xml escape.xsl
and you get:
<publisher>O'Reilly & Associates</publisher>
In escape.xsl , escaping is turned off so that & is not preserved. You get only the ampersand in the result. The publisher element, which appears in both escape.xsl and noescape.xsl , is a literal result element. Let me explain what that is.