Cover | Table of Contents | Colophon
<td>12304</td>
http://xml.apache.org/xalan-j/ and download the latest stable build of the code. (If you're feeling brave, feel free to download last night's build instead.)CLASSPATH. The three files include the .jar file for the Xerces parser, the .jar file for the Xalan stylesheet engine itself, and the .jar file for the Bean Scripting Framework. As of this writing, the .jar files are named xerces.jar, xalan.jar, and bsf.jar.java org.apache.xalan.xslt.Process
java org.apache.xalan.xslt.Process
=xslproc options:
-IN inputXMLURL
[-XSL XSLTransformationURL]
[-OUT outputURL]
[-LXCIN compiledStylesheetFileNameIn]
[-LXCOUT compiledStylesheetFileNameOutOut]
<?xml version="1.0"?> <greeting> Hello, World! </greeting>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<xsl:apply-templates select="greeting"/>
</xsl:template>
<xsl:template match="greeting">
<html>
<body>
<h1>
<xsl:value-of select="."/>
</h1>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0"?> <greeting> Hello, World! </greeting>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<xsl:apply-templates select="greeting"/>
</xsl:template>
<xsl:template match="greeting">
<html>
<body>
<h1>
<xsl:value-of select="."/>
</h1>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
java org.apache.xalan.xslt.Process -in greeting.xml -xsl greeting.xsl -out greeting.html
<html> <body> <h1> Hello, World! </h1> </body> </html>
<xsl:output> element that specifies HTML as the output format and two <xsl:template> elements that specify how parts of our XML document should be transformed. <xsl:stylesheet> element is typically the root element of an XSLT stylesheet.
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:stylesheet> element defines the version of XSLT we're using, along with a definition of the xsl namespace. To be compliant with the XSLT specification, your stylesheet should always begin with this element, coded exactly as shown here. Some stylesheet processors, notably Xalan, issue a warning message if your <xsl:stylesheet> element doesn't have these two attributes with these two values. For all examples in this book, we'll start the stylesheet with this exact element, defining other namespaces as needed. xml, html, and text. We're creating an HTML document, so HTML is the output method we want to use. In addition to these three methods, an XSLT processor is free to define its own output methods, so check your XSLT processor's documentation to see if you have any other options. <xsl:output method="html"/>
method="xml", you can use doctype-public and doctype-system to define the public and system identifiers to be used in the the document type declaration. If you're using method="xml" or method="html", you can use the indent attribute to control whether or not the output document is indented. The discussion of the
<xsl:output>
element in Appendix A has all the details."/", the XPath expression for the document's root element.
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
doctype-public="-//W3C//DTD SVG 20001102//EN"
doctype-system=
"http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd"/>
<xsl:template match="/">
<svg width="8cm" height="4cm">
<g>
<defs>
<radialGradient id="MyGradient"
cx="4cm" cy="2cm" r="3cm" fx="4cm" fy="2cm">
<stop offset="0%" style="stop-color:red"/>
<stop offset="50%" style="stop-color:blue"/>
<stop offset="100%" style="stop-color:red"/>
</radialGradient>
</defs>
<rect style="fill:url(#MyGradient); stroke:black"
x="1cm" y="1cm" width="6cm" height="2cm"/>
<text x="4cm" y="2.2cm" text-anchor="middle"
style="font-family:Verdana; font-size:24;
font-weight:bold; fill:black">
<xsl:apply-templates select="greeting"/>
</text>
</g>
</svg>
</xsl:template>
<xsl:template match="greeting">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
<greeting> elements similarly. We've gone over the basics of what stylesheets are and how they work.http://www.mulberrytech.com/xsl/xsl-list/index.html.<para> element, the quantity attribute of the <part-number> element, all <first-name> elements that contain the text "Joe", and many other variations. An XSLT stylesheet uses XPath expressions in the match and select attributes of various elements to indicate how a document should be transformed. In this chapter, we'll discuss XPath in all its glory.$x*6) and Unix-like path expressions (such as /sonnet/author/last-name). In addition to the basic syntax, XPath provides a set of useful functions that allow you to find out various things about the document.
<?xml version="1.0"?>
<?xml-stylesheet href="sonnet.xsl" type="text/xsl"?>
<?cocoon-process type="xslt"?>
<!DOCTYPE sonnet [
<!ELEMENT sonnet (auth:author, title, lines)>
<!ATTLIST sonnet public-domain CDATA "yes"
type (Shakespearean | Petrarchan) "Shakespearean">
<!ELEMENT auth:author (last-name,first-name,nationality,
year-of-birth?,year-of-death?)>
<!ELEMENT last-name (#PCDATA)>
<!ELEMENT first-name (#PCDATA)>
<!ELEMENT nationality (#PCDATA)>
<!ELEMENT year-of-birth (#PCDATA)>
<!ELEMENT year-of-death (#PCDATA)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT lines (line,line,line,line,
line,line,line,line,
line,line,line,line,
line,line)>
<!ELEMENT line (#PCDATA)>
]>
<!-- Default sonnet type is Shakespearean, the other allowable -->
<!-- type is "Petrarchan." -->
<sonnet type="Shakespearean">
<auth:author xmlns:auth="http://www.authors.com/">
<last-name>Shakespeare</last-name>
<first-name>William</first-name>
<nationality>British</nationality>
<year-of-birth>1564</year-of-birth>
<year-of-death>1616</year-of-death>
</auth:author>
<!-- Is there an official title for this sonnet? They're
sometimes named after the first line. -->
<title>Sonnet 130</title>
<lines>
<line>My mistress' eyes are nothing like the sun,</line>
<line>Coral is far more red than her lips red.</line>
<line>If snow be white, why then her breasts are dun,</line>
<line>If hairs be wires, black wires grow on her head.</line>
<line>I have seen roses damasked, red and white,</line>
<line>But no such roses see I in her cheeks.</line>
<line>And in some perfumes is there more delight</line>
<line>Than in the breath that from my mistress reeks.</line>
<line>I love to hear her speak, yet well I know</line>
<line>That music hath a far more pleasing sound.</line>
<line>I grant I never saw a goddess go,</line>
<line>My mistress when she walks, treads on the ground.</line>
<line>And yet, by Heaven, I think my love as rare</line>
<line>As any she belied with false compare.</line>
</lines>
</sonnet>
<!-- The title of Sting's 1987 album "Nothing like the sun" is -->
<!-- from line 1 of this sonnet. -->match and select attributes of various XSLT elements. Those location paths described the parts of the XML document we wanted to work with. Most of the XPath expressions you'll use are location paths, and most of them are pretty simple. Before we dive in to the wonders of XPath, we need to discuss the context.sonnet is a directory at the root level of the filesystem. The sonnet directory would, in turn, contain directories named auth:author, title, and lines. In this example, the context would be the current directory. If I go to a command line and execute a particular command (such as dir *.js), the results I get vary depending on the current directory. Similarly, the results of evaluating an XPath expression will probably vary based on the context. <li> elements in a given document. The context size refers to the number of <li> items selected by that expression, and the context position refers to the position of the <table> element like this:
<table border="{@size}"/>
@size is evaluated, and its value, whatever that happens to be, is inserted into the output tree as the value of the border attribute. Attribute value templates can be used in any literal result elements in your stylesheet (for HTML elements and other things that aren't part of the XSLT namespace, for example). You can also use attribute value templates in the following XSLT attributes:name and namespace attributes of the <xsl:attribute> element
name and namespace attributes of the <xsl:element> element
format, lang, letter-value, grouping-separator, and grouping-size attributes of the <xsl:number> element
name attribute of the <xsl:processing-instruction> element
lang, data-type, order, and case-order attributes of the <xsl:sort> element
node-set
boolean
true or false. Be aware that the true or false strings have no special meaning or value in XPath; see Section 4.2.1.2 in Chapter 4 for a more detailed discussion of boolean values. number
integer (or int) datatype does not exist in XPath and XSLT. Specifically, all numbers are implemented as IEEE 754 floating-point numbers, the same standard used by the Java float and double primitive types. In addition to ordinary numbers, there are five special values for numbers: positive and negative infinity, positive and negative zero, and NaN, the special symbol for anything that is not a number.string
namespace nodes.<sonnet> element. The <sonnet> element, in turn, contains two attributes and an <auth:author> element. The <auth:author> element contains a namespace node and an element. Be aware that this stylesheet has its limitations; if you throw a very large XML document at it, it will generate an HTML file with many levels of nested tables—probably more levels than your browser can handle.
<xsl:template match="/">
<html>
<head>
<title>XPath view of your document</title>
<style type="text/css">
<xsl:comment>
span.literal { font-family: Courier, monospace; }
</xsl:comment>
</style>
</head>
<body>
<h1>XPath view of your document</h1>
<p>The structure of your document (as defined by
the XPath standard) is outlined below.</p>
<table cellspacing="5" cellpadding="2" border="0">
<tr>
<td colspan="7">
<b>Node types:</b>
</td>
</tr>
<tr>
<td bgcolor="#99CCCC"><b>root</b></td>
<td bgcolor="#CCCC99"><b>element</b></td>
<td bgcolor="#FFFF99"><b>attribute</b></td>
<td bgcolor="#FFCC99"><b>text</b></td>
<td bgcolor="#CCCCFF"><b>comment</b></td>
<td bgcolor="#99FF99"><b>processing instruction</b></td>
<td bgcolor="#CC99CC"><b>namespace</b></td>
</tr>
</table>
<br /><xsl:if>, <xsl:choose>, and <xsl:for-each>. The first two are much like the if and case statements you may be familiar with from other languages, while the for-each element is significantly different from the for or do-while structures in other languages. We'll discuss all of them here.<xsl:if> element looks like this:<xsl:if test="count(zone) > 2"> <xsl:text>Applicable zones: </xsl:text> <xsl:apply-templates select="zone"/> </xsl:if>
<xsl:if> element, surprisingly enough, implements an if statement. The element has only one attribute, test. If the value of test evaluates to the boolean value true, then all elements inside the <xsl:if> are processed. If <xsl:if>, <xsl:choose>, and <xsl:for-each>. The first two are much like the if and case statements you may be familiar with from other languages, while the for-each element is significantly different from the for or do-while structures in other languages. We'll discuss all of them here.<xsl:if> element looks like this:<xsl:if test="count(zone) > 2"> <xsl:text>Applicable zones: </xsl:text> <xsl:apply-templates select="zone"/> </xsl:if>
<xsl:if> element, surprisingly enough, implements an if statement. The element has only one attribute, test. If the value of test evaluates to the boolean value true, then all elements inside the <xsl:if> are processed. If test evaluates to false, then the contents of the <xsl:if> element are ignored. (If you want to implement an if-then-else statement, check out the <xsl:choose> element described in the next section.) > instead of > in the attribute value. You're always safe using > here, although some XSLT processors process the greater-than sign correctly if you use > instead. If you need to use the less-than operator (<), you'll have to use the < entity. The same holds true for the less-than-or-equal operator (<=) and the greater-than-or-equal (>=) operators. See Section B.4.2 for more information on this topic.
<xsl:if> element is pretty simple, but it's the first time we've had to deal with boolean values. These values will come up later, so we might as well discuss them here. Attributes like the test attribute of the <xsl:if> element convert whatever their values happen to be into a boolean value. If that boolean value is <xsl:apply-templates> element to invoke other templates. You can think of this as a limited form of polymorphism; a single instruction is invoked a number of times, and the XSLT processor uses each node in the node-set to determine which <xsl:template> to invoke. Most of the time, this is what we want. However, sometimes we want to invoke a particular template. XSLT allows us to do this with the <xsl:call-template> element. name.<xsl:call-template> element to invoke the named template.
<xsl:template name="createMasthead">
<!-- interesting stuff that generates the masthead goes here -->
</xsl:template>
...
<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="title"/></title>
</head>
<body>
<xsl:call-template name="createMasthead"/>
...
<xsl:call-template> to invoke those templates and create the look and feel you want. <xsl:import> or <xsl:include>), you can create a set of stylesheets that generate the look and feel of the web site you want. If you decide to redesign your web site, redesign the stylesheets that define the common graphical and layout elements. Change those stylesheets, regenerate your web site, and voila! You will see an instantly updated web site. (See Chapter 9 for an example.)
<xsl:param> and <xsl:with-param> elements allow you to pass parameters to a template. You can pass templates with either the <call-template> element or the <apply-templates> element; we'll discuss the details in this section. <xsl:param> element. Here's an example of a template that defines two parameters:<xsl:template name="calcuateArea"> <xsl:param name="width"/> <xsl:param name="height"/> <xsl:value-of select="$width * $height"/> </xsl:template>
width and height, and outputs their product. select attribute on the <xsl:param> element:
<template name="addTableCell">
<xsl:param name="bgColor" select="'blue'"/>
<xsl:param name="width" select="150"/>
<xsl:param name="content"/>
<td width="{$width}" bgcolor="{$bgColor}">
<xsl:apply-templates select="$content"/>
</td>
</template>
bgColor and width are 'blue' and 150, respectively. If we invoke this template without specifying values for these parameters, the default values are used. Also notice that we generated the values of the width and bgcolor attributes of the HTML <td> tag with attribute value templates, the values in curly braces. For more information, see Section 3.3 in Chapter 3.blue, but we didn't do it around the value 150. Without the single quotes around blue, the XSLT processor assumes we want to select all the <blue> elements in the current context, which is probably not what we want. The XSLT processor is clever enough to realize that the value <xsl:variable> element, which allows you to store a value and associate it with a name. <xsl:variable> element can be used in three ways. The simplest form of the element creates a new variable whose value is an empty string (""). Here's how it looks:<xsl:variable name="x"/>
x, whose value is an empty string. (Please hold your applause until the end of the section.)select attribute to the <xsl:variable> element:<xsl:variable name="favouriteColour" select="'blue'"/>
blue is used as the value of the variable. If we had left out the single quotes, this would mean the value of the variable is that of all the <blue> elements in the current context, which definitely isn't what we want here. 35, Xalan, XT, and Saxon all assume that I mean 35 as a literal value, not as an element name. Although this works with many XSLT processors, you're safer to put the single quotes around the numeric values anyway. A further aside: the value here is the string "35", although it can be converted to a number easily. <xsl:variable> element is to put content inside it. Here's a brief example:
<xsl:variable name="y">
<xsl:choose>
<xsl:when test="$x > 7">
<xsl:text>13</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>15</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>(^) in front of all ampersands (&)
mkdir xslt & chdir xslt
Jones & Son as the value of the company field in a row of the database, we need to change it to Jones ^& Son before we try to run the SQL command. (^)) in front of all vertical bars (|)
xsl:for-each element is not a for loop; it's merely an iterator across a group of nodes. However, if you simply must implement a for loop, there's a way to do it. (Get ready to use recursion, though.)for loop processor. If you think about a traditional for loop, it has several properties:for loop begins. Typically the initialization statements refer to an index variable that is used to determine whether the loop should continue. true, the loop continues; if it is ever false, the loop exits. for (int i=0; i<length; i++)
i=0, the index variable (the variable whose value determines whether we're done or not) is i, the boolean expression we use to test whether the loop should continue is i<length, and the increment statement is i++. i when it invokes our for loop processor. i++, we'll require the caller to set the value of the local variable for loop now, but what about a stylesheet that generates another stylesheet that emulates the for loop? As we beat this dead horse one more time, we'll create a stylesheet that generates the iteration for us, along with an XML syntax that automates the process.
<?xml version="1.0"?>
<html xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<head>
<title>Text generated by our for loop processor</title>
</head>
<body>
<h1>Text generated by our for loop processor</h1>
<table border="1">
<tr>
<th>Iteration #</th>
<th>Value of <i>i</i></th>
</tr>
<for-loop index-variable="0" increment="1"
operator="<=" test-value="10">
<tr>
<td align="center">
<xsl:value-of select="$iteration"/>
</td>
<td align="center">
<xsl:value-of select="$i"/>
</td>
</tr>
</for-loop>
</table>
</body>
</html>