Presents your
XML E-NEWSLETTER for January 8, 2003
<------------------------------------------->
ADD CUSTOM XSLT FUNCTIONALITY WITH JAVA
Developing XSLT solutions can be simple and require a small amount
of effort to perform the translation. Sometimes, however, the source
and target documents are complex and different. In many of these
cases, complex transformations are carried out by equally complex XSLT
solutions.
Some transformations may not even be possible with stock XSLT
functionality. For these cases, you can add new functions to your stylesheets
using the Apache Xalan XSLT engine and custom Java extensions.
A SAMPLE PROBLEM
Let's start by examining a sample problem. Suppose you're transforming
an XML document and you need to perform some advanced operation in the
middle of the transformation. You may need to reference a lookup table
stored in a database or possibly access a Web service. The function may
be a simple one that's not provided directly by XSLT.
We'll imagine we have a simple order XML document, as shown in LISTING
1. The problem is that our transformation process needs to reverse the
characters in the Description element. Maybe it's not exactly a
real-world scenario, but it does illustrate the process of hooking Java
functionality into an XSL transformation:
Listing 1: order.xml
-
19723
Mechawidget Flange
-
87123
Hydrafluant Magnet
-
662354
Generic Rubber Seal
-
967623
Fluxating Plasmatron
THE SOLUTION
Our solution is to use the Apache Xalan XSL processor and extend it with
a custom Java class. The Java component will perform the actual reversal
of the string data. The XSL stylesheet will access the Java class, pass
XML data to it, and display the return value in the resulting XML
document. Each of these steps is outlined below.
THE JAVA PART
In order to solve this problem, we first need the Java code that will do
the work. In this case, we'll use a simple string reversal class, as
shown in LISTING 2:
Listing 2: Reverse.java
public class Reverse {
public static String reverse(String str) {
String retval = "";
char[] b = new char[str.length()];
str.getChars(0, str.length(), b, 0);
for (int i = (b.length - 1); i >= 0; i--) {
retval += b[i];
}
return retval;
}
}
This class has a single static method called reverse. The method takes a
one String parameter and returns a string. The functionality to reverse
the string involves reading the characters as an array from the String
class and iterating through them from the last character to the first.
You'll need to compile this code into a binary Java class file. Because
the class is not in a package, it needs to reside in the root of your
classpath (or the root of one of your classpath directories).
THE XSLT PART
In order to use Java classes within the XSL stylesheet, you need to
declare a special XML namespace. The namespace identifies the format for
calling the Java classes. There are three different namespace formats
you can use; we'll illustrate only one. We'll use the Java format, which looks
like this:
xmlns:java=http://xml.apache.org/xalan/java
In addition to declaring the Java namespace, we'll also need to specify
the exclude-result-prefixes attribute in the element.
This attribute will exclude the Java namespace in the output document.
To actually call the Java component from within the XSL stylesheet, you
specify the class and the method and pass in the parameters. The class
must be prefixed with the namespace. For example, to call the reverse()
method of our Reverse class, we might use something like this:
The value passed into the method can either be a static value, as above,
or a value from the XML document. LISTING 3 shows our XSL stylesheet,
which includes the namespace declaration, the exclude-result-prefixes
attribute, and the call to the reverse() method for the value of the
element.
Listing 3: order.xsl
-
REUSABLE COMPONENTS
Part of the value of using Java classes within your stylesheets is that
it allows you to reuse existing Java components. For example, if you have
a class that performs specific business logic or accesses information
from a data warehouse or enterprise application, then reusing that
component within your XSL applications can be very powerful. Likewise,
you may be able to reuse the Java extensions you create for XSL in other
enterprise applications.
Brian Schaffner is a senior consultant for Fujitsu Consulting. He
provides architecture, design, and development support for Fujitsu's
Telcom360 group.
----------------------------------------