Skip to main content

skip to main content

developerWorks  >  XML  >

Tip: Using JDOM and XSLT

How to find the right input for your processor

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Intermediate

Brett McLaughlin (brett@newInstance.com), Author/Editor, O'Reilly Media, Inc.

01 Mar 2001

In this tip, Brett McLaughlin tells how to avoid a common pitfall when working with XSLT and the JDOM API for XML developers working in Java. You'll learn how to take a JDOM document representation, transform it using the Apache Xalan processor, and obtain the resulting XML as another JDOM document. Transforming a document using XSLT is a common task, and JDOM makes the transformation go quite easily once you know how to avoid the missteps. The code demonstrates how to use JDOM with the new Apache Xalan 2 processor (for Java).

Being one of the co-creators of JDOM, I simply couldn't pass up the chance to throw in a few JDOM tips in a series of XML tips and tricks. This tip provides the answer to one of the most common questions I get about JDOM: "How do I use JDOM and XSLT together?" People aren't sure how to take a JDOM Document object and feed it into an XSLT processor. The confusion often arises because most XSLT processors take either DOM trees or SAX events as input streams. In other words, there is not one obvious way to provide a JDOM Document as input in all cases. So how do you interface JDOM with those processors?

The key to solving this problem is understanding the input and output options. First determine the input formats that your XSLT processor accepts. As I mentioned above, you'll usually be able to feed a DOM tree or I/O stream into the processor. But which of those is the faster solution? You're going to have to do a little digging to answer that question. (That's right, I'm not going to give you a specific answer, but a method for figuring it out.) Check out your processor's documentation, and even ask the vendor for the particular format that is used internally.

Many processors currently use a DOM tree as the internal document representation. For these processors, passing in a DOM tree is the best option because the processor can use that structure immediately, without any internal conversion. Converting your JDOM Document to a stream (using XMLOutputter) would waste time, as that stream is just going to be converted back into a DOM tree. So always try to find the shortest path between JDOM and the processor's internal representation. If you need to feed the processor a DOM tree, use JDOM's DOMOutputter, and if you need to feed the processor SAX, use SAXOutputter. In either case, the key is connecting the correct output format for your JDOM Document with the best solution for input to your XSLT processor.

To give you a more specific idea of how this works, let's look at using the Apache Xalan processor and, in particular, the new Xalan 2 (the Java version is actually called Xalan-J 2, but you get the idea). This open-source, Java-based XSLT processor can work most efficiently with an I/O stream input. While Xalan makes use of the DOM, it uses a fairly customized implementation that allows Xalan to perform at peak speeds. For that reason, feeding in a DOM tree does not end up not saving as much time as you would think. Listing 1 takes a JDOM Document, converts it to an output stream, and then feeds that stream into the Xalan XSLT processor. Once the processor returns the transformed XML, that XML is converted back into a JDOM Document for further processing. In other words, JDOM in, JDOM out, and transformation occurs. Voila!


Listing 1. Using JDOM with Xalan-J 2
                

// JDOM imports
import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
// Xalan-J 2 imports
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public Document transform(Document sourceDoc, File stylesheetFile) {
    // Set up the XSLT stylesheet for use with Xalan-J 2
    TransformerFactory transformerFactory =
TransformerFactory.newInstance();
    Templates stylesheet = transformerFactory.newTemplates(
            new StreamSource(stylesheetFile));
    Transformer processor = stylesheet.newTransformer();
    // Use I/O streams for source files
    PipedInputStream sourceIn = new PipedInputStream();
    PipedOutputStream sourceOut = new PipedOutputStream(sourceIn);
    StreamSource source = new StreamSource(sourceIn);
    // Use I/O streams for output files
    PipedInputStream resultIn = new PipedInputStream();
    PipedOutputStream resultOut = new PipedOutputStream(resultIn);
    // Convert the output target for use in Xalan-J 2
    StreamResult result = new StreamResult(resultOut);
    // Get a means for output of the JDOM Document
    XMLOutputter xmlOutputter = new XMLOutputter();
    // Output to the I/O stream
    xmlOutputter.output(sourceDoc, sourceOut);
    sourceOut.close();
    // Feed the resultant I/O stream into the XSLT processor
    processor.transform(source, result);
    resultOut.close();
    // Convert the resultant transformed document back to JDOM
    SAXBuilder builder = new SAXBuilder();
    Document resultDoc = builder.build(resultIn);
    return resultDoc;
}

By the way, thanks to Jan Hecking on the jdom-interest mailing list for the code sample that I modified slightly in this tip.



Resources



About the author

Author photo

Brett McLaughlin has worked in computers since the Logo days. (Remember the little triangle?) In recent years, he's become one of the most well-known authors and programmers in the Java and XML communities. He's worked for Nextel Communications, implementing complex enterprise systems; at Lutris Technologies, actually writing application servers; and most recently at O'Reilly Media, Inc., where he continues to write and edit books that matter. His most recent book, Java 5.0 Tiger: A Developer's Notebook , is the first book available on the newest version of Java technology, and his classic Java and XML remains one of the definitive works on using XML technologies in the Java language.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top