Professional Documents
Culture Documents
Use XSL and servlets to style your XML data ow, you've come so far. A year ago you didn't
know what XML was, but now it's everywhere. You're storing XML in databases and using it in
middleware, and now you want to present that data to a browser. That's where XSL can help.
XSL can help you turn your XML into HTML. Moreover, servlets provide a powerful medium to
perform those translations as they reside on the server and have access to all the features of
server-side Java.
In this article, we'll cover the basics of XSL and XSL processors. If you don't know much about
XML, you may want to first read Mark Johnson's excellent XML article, " Programming XML in
Java, Part 1 ."
Our example will use a servlet to turn well-formed XML into HTML. If you need to learn more
about servlets, please refer to Sun's servlets tutorial (see Resources ).
XML and XSL
The process of transforming and formatting information into a rendered result is called styling.
Two recommendations from the W3C come together to make styling possible: XSL
Transformations (XSLT), which allows for a reorganization of information, and XSL, which
specifies the formatting of the information for rendering.
With those two technologies, when you put your XML and XSL stylesheet into an XSL
processor, you don't just get a prettied up version of your XML. You get a result tree that can be
expanded, modified, and rearranged.
An XSL processor takes a stylesheet consisting of a set of XSL commands and transforms it,
using an input XML document. Let's take a look at a simple example.
Below we see a small piece of XML, describing an employee. It includes his name and title. Let's
assume that we would like to present that in HTML.
Joe Shmo
Then we could use a stylesheet, such as the one below, to generate the HTML above. The
stylesheet could reside in a file or database entry:
:
version="1.0">
.
.
.
If there are any extensions referenced, the namespace must be specified. For example, if you
were going to use Java, you would specify this namespace:
xmlns:java="http://xml.apache.org/xslt/java"
Pattern matching
When selecting in a stylesheet, a pattern is used to denote which element or attribute we want to
access. The syntax is simple: specify the node you want, using / to separate the elements.
Notice that in the sample XML code above we matched our template on / , which is the root
node. We could have, however, matched on the employee node. Then a select statement could
just refer to the name node instead of employee/name .
For example, if we had the following XML:
Joe Shmo
Attributes can also be selected. The employee id could be accessed by saying employee/@id .
Groups of nodes can be accessed by using employee/* . A specific employee could be located
using employee/@id='03432' .
Pattern matching allows us to select specific values out of our XML document. The
Accessing elements versus attributes
Command
Result
Joe Shmo
03432
Templates
Templates provide a way to match nodes in an XML document and perform operations on them.
The syntax for a template is:
.
.
.
The template is matched on a node name, then all the stylesheet commands in that template are
applied. We can call templates in our stylesheet by using the apply-templates command:
We can call this template anywhere there is a name node to be referenced, using this:
Logical commands
There are a few structures available for doing ifs and loops. Let's take a look at the syntax.
Choose command
The choose command provides a structure to test different situations.
stylesheet commands
stylesheet commands
The first successful test will result in that block's stylesheet commands executing. If all the tests
fail, the otherwise block is executed. You may have as many when blocks as you want. The
otherwise block must always be present; if you don't want to do anything in your otherwise
block, just put:
If command
The if command provides only a single test and doesn't have any kind of else structure available.
If you need to have an else, use the choose command.
...
...
For example, if you had more than one employee in your XML document, and you wanted to
loop through all the managers, you could use a statement such as this:
...
Variables
The variable command provides a way to set a variable and access it later. The extension
mechanism uses variables to store the values retrieved from extensions:
assign value to count
here
The variable count can be accessed by using $count later in the stylesheet:
Parameters
You can pass parameters to your stylesheet, using the param tag. You can also specify a default
value in a select statement. The default is a string, so it must be in single quotes:
You can set the parameters you are passing to your stylesheet on your XSLProcessor object:
processor.setStylesheetParam("param1", processor.createXString("value"));
Extensions
Extensions add functionality to a stylesheet. XSL comes with some basic functions:
sum() -- Sum the values in designated nodes
count() -- Count the nodes
position() -- Returns the position of the current node in a loop
last() -- Test whether this is the last node; this function returns a boolean value
If you want additional functionality, you need to use extensions. Extensions can be called
anywhere a value can be selected. Extensions to a stylesheet can be written in Java or JavaScript,
among other languages. We'll concentrate on Java extensions in this article.
In order to call extensions in Java, the java namespace must be specified in your stylesheet
declaration:
xmlns:java="http://xml.apache.org/xslt/java"
Any calls to Java extensions would be prefaced with java: . (Note: You don't have to call your
namespace java ; you can call it whatever you want.)
You can do three things with Java extensions: create instances of classes, call methods on those
classes, or just call static methods on classes. Table 2 shows syntax that can be used to reference
Java objects.
Instantiate a class: prefix:class.new (args) Example: variable myVector
select"java:java.util.Vector.new()"
Call a static method: prefix:class.methodName (args) Example: variable myString
select="java:java.lang.String.valueOf(@quantity))"
Call a method on an object: prefix:methodName (object, args) Example: variable myAdd
select="java:addElement($myVector, string(@id))" Table 2. Three ways to use Java objects
(For more on XSL, see Elliotte Harold's The XML Bible in Resources .)
The XSL Processor API
For our example, we will use Lotus' implementation of Apache's XSL processor Xalan (see
Resources ). We'll use the following classes in our servlet example:
Class com.lotus.xsl.XSLProcessor
com.lotus.xsl.XSLProcessor is the processor that implements the functionality defined in
org.apache.xalan.xslt.XSLTProcessor . The default constructor can be used and processing can
take place using the process() method, as seen below:
void process(XSLTInputSource inputSource, XSLTInputSource stylesheetSource,
XSLTResultTarget outputTarget)
The process() method transforms the source tree to the output in the given result tree target.
The void reset() method, to be used after process() , resets the processor to its original state.
The process() method is overloaded 18 times. Each signature provides a different way to process
your XML and XSL. Some return an org.w3c.dom.Document object. I have found that the above
process() method is the handiest; the documentation recommends its use because of the
XSLTInputSource (used to read in XML or XSL) and XSLTResultTarget (used to write out the
results) classes, which we examine next in turn.
Class com.lotus.xsl.
XSL stands for E X tensible Stylesheet Language. The World Wide Web Consortium (W3C)
started to develop XSL because there was a need for an XML-based Stylesheet Language. Thus
it is a language for expressing Stylesheets.
A stylesheet specifies the presentation of XML information using two basic categories of
techniques:
• An optional transformation of the input document into another structure.
• A description of how to present the transformed information.
The components of the XSL language
The full XSL language logically consists of three component languages, which are described in
three W3C (World Wide Web Consortium) Recommendations:
1. XPath: XML Path Language is an expression language used by XSLT to access or refer
specific parts of an XML document
2. XSLT: XSL Transformations is a language for describing how to transform one XML
document (represented as a tree) into another.
3. XSL-FO: Extensible Stylesheet Language Formatting Objects is a language for
formatting XML documents and Formatting Properties.
Understanding XSL Stylesheet Structure
(a) XSLT namespace
The XSL stylesheet starts with the root element <xsl:stylesheet> or <xsl:transform> that
declares the document to be an XSL style sheet.
The correct way to declare an XSL style sheet according to the W3C XSLT Recommendation is:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
or:
<xsl:transform version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
Since an XSL style sheet is an XML document itself, it always begins with the XML declaration:
<?xml version="1.0" ?>
To get access to the XSLT elements, attributes and features we must declare the XSLT
namespace at the top of the document.
The xmlns:xsl="http://www.w3.org/1999/XSL/Transform" points to the official W3C XSLT
namespace. If you use this namespace, you must also include the attribute version="1.0". This
specification uses a prefix of xsl: for referring to elements in the XSLT namespace. However,
XSLT stylesheets are free to use any prefix.
Now set it up to produce HTML-compatible output:
<xsl:stylesheet
...
>
<xsl:output method="html"/>
...
</xsl:stylesheet>
(b) Stylesheet Element
The <xsl:template> Element
An XSL style sheet consists of a set of rules that are called templates. Each template "matches"
some set of elements in the source tree and then describes the contribution that the matched
element makes to the result tree.
Most templates have the following form:
<xsl:template match="/">
<html><body>
<xsl:apply-templates/>
</body></html>
</xsl:template>
Before processing can begin, the part of the XML document with the information to be copied to
the output must be selected with an XPath expression. The selected section of the document is
called a node and is normally selected with the match operator.
In the above statements, the <xsl:template> element defines a template. The match="/" attribute
associates the template with the root node of the XML source document. Another approach is to
match the document element (the element that includes the entire document).
The <xsl:apply-templates> Element
The <xsl:apply-templates> element applies a template to the current element or to the current
element's child nodes.
If we add a select attribute to the <xsl:apply-templates> element it will process only the child
element that matches the value of the attribute. We can use the select attribute to specify the
order in which the child nodes are processed.
The <xsl:value-of> Element
The <xsl:value-of> element can be used to extract the value of an XML element and add it to the
output stream of the transformation. For example, the given expression will select the value of
Emp_Id attribute of the specified element and write to the output:
<xsl:value-of select="Emp_Id"/>
or
<xsl:value-of select="Employee-
Detail/Employee/Emp_Id"/>
Note: The value of the select attribute is an XPath expression. An XPath expression works like
navigating a file system; where a forward slash (/) selects subdirectories.
The <xsl:for-each select="elementName "> Element
The 'for-each' expression is a loop that processes the same instructions for these elements. The
XSL <xsl:for-each> element can be used to select every XML element of a specified node-set.
For example, the given expression finds all ‘Employee' elements in the ‘Employee-Detail'
element context using the XPath expression ‘Employee-Detail/ Employee'. If the selected node
contains all elements in the root, all of the ‘Employee-Detail' elements will be selected.
<xsl:for-each select="Employee">
<xsl:value-of select="Emp_Id"/>
<xsl:value-of
select="Emp_Name"/>
</xsl:for-each>
Now we will develop a class in Java that takes both XML and XSL file as an input and
transforms them to generate a formatted HTML file.
Here is the source code of the SimpleXMLTransform.java:
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class SimpleXMLTransform {
static public void main(String[] arg) {
if(arg.length != 3) {
System.err.println("Usage: SimpleXMLTransform " +
"<input.xml> <input.xsl> <output>");
System.exit(1);
}
String inXML = arg[0];
String inXSL = arg[1];
String outTXT = arg[2];
This program uses three arguments to take inputs from the command line: arg[0] is for XML
file, arg[1] is for XSL file, and arg[2] is for taking the name of the html file that will be
generated after the transformation.
As in the earlier section, we have described the working process of XSLT APIs. First, this
program creates an instance of the TransformerFactory class. The new instance of the
Transformer class is created using an “ xslStream” instance of the StreamSource class. This
instance of the Transformer class required for transformation to generate the formatted output as
a result object. Its method transform(in,out) takes two arguments: the XML document as a
source object and the result document as an output object in the form of HTML .
4. Compile and Run the Program
C:\nisha\xslt>javac SimpleXMLTransform.java
C:\nisha\xslt>java SimpleXMLTransform emp.xml emp.xsl
emp.html
The generated HTML file is:emp.html
The format of the generated output file “emp.html” will look like this: