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. ----------------------------------------