5.4 JAXP

I l @ ve RuBoard

The next API on the list is one which readers should realize is not a parser, or even an API for parsing XML. JAXP is the Java API for XML Processing and is simply an abstraction layer, a thin shim that sits on top of the SAX and DOM APIs. JAXP performs no XML parsing itself, but instead defers this task to the underlying SAX and DOM APIs. The same thing is true for JAXP's XML transformation processing capabilities.

You should always attempt to use JAXP in a J2EE application. With the release of JAXP 1.1 [6] and support for SAX 2.0 and DOM Level 2, JAXP provides the baseline tool support required for solid Java and XML programming. You'll be able to migrate applications more easily and change parser and processor vendors at will ”with minimal impact on your applications. JAXP also has shown no adverse performance effects, so there is no reason to avoid using JAXP.

[6] JAXP 1.2 offers even more, such as support for XML schema. However, the SAX 2.0 and DOM Level 2 compliance is of much greater import, so I recommend using JAXP 1.1 as a minimum requirement rather than Version 1.2.

At times, you will decide you need to use vendor-specific extensions to a parser or processor. In these cases, JAXP will obviously not suffice. However, I still recommend using JAXP, except in the specific portions of your code that reference these vendor-specific features.

5.4.1 Don't Be Afraid to Use Format Transformations

Here, we will discuss a core feature of JAXP that is underused: conversion from one API format (SAX, a stream, or DOM) to another. While this has always been one of the basic features of JAXP, it is rarely used, probably due to a lack of understanding of JAXP's Transformation API for XML, or TRaX.

An example is the best way to illustrate this sort of format transformation. Example 5-17 shows a helper class that will perform these conversions for you, so you don't have to constantly deal with new Transformer instances and the JAXP TransformerFactory .

Example 5-17. Format conversion helper class
 package com.oreilly.xml;     import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource;     public class FormatConverter {         private static boolean initialized = false;         private static Transformer transformer;         private static void initialize(  ) throws TransformerException {         TransformerFactory factory = TransformerFactory.newInstance(  );         transformer = factory.newTransformer(  );         initialized = true;     }         public static void convert(StreamSource source, SAXResult result)          throws TransformerException {             transformer.transform(source, result);     }         public static void convert(StreamSource source, DOMResult result)          throws TransformerException {             transformer.transform(source, result);     }         public static void convert(SAXSource source, DOMResult result)          throws TransformerException {             transformer.transform(source, result);     }         public static void convert(SAXSource source, StreamResult result)          throws TransformerException {             transformer.transform(source, result);     }         public static void convert(DOMSource source, StreamResult result)          throws TransformerException {             transformer.transform(source, result);     }         public static void convert(DOMSource source, SAXResult result)          throws TransformerException {             transformer.transform(source, result);     }     static {initialize();} } 

This example takes in the various types of TrAX (JAXP) sources and outputs to the various TrAX outputs through the Result interface. While this is a pretty trivial class, it actually contains quite a bit of power. If you've used DOM before, you're probably aware that the process of serializing a DOM tree to a file, or to any other kind of stream, is typically vendor-specific. It moves your vendor-neutral DOM code to something dependent on some project or implementation. However, the FormatConverter class takes care of this handily:

 // Get your DOM tree built up, manipulated, and ready for serialization. Document doc = getDOMTreeSomehow(  );     // Set up input and output. javax.xml.transform.dom.DOMSource domSource=      new javax.xml.transform.dom.DOMSource(doc); javax.xml.transform.stream.StreamResult streamResult =     new javax.xml.transform.stream.StreamResult("output.xml");     // Serialize. FormatConverter.convert(domSource, streamResult); 

Through this transformation, often called the identity transformation , serialization becomes trivial and requires no vendor-specific code at all. You can use the same method with different parameters as input to transform an input source ( StreamSource ) to a DOM tree ( DOMResult) , or convert from SAX ( SAXSource ) to a file ( StreamResult ) or a DOM tree ( DOMResult ). Just to be sure you get the idea, here's another sample, which reads in a file and converts it to a DOM tree:

 StreamSource source = new StreamSource("person.xml"); DOMResult result = new DOMResult(  );     // Convert (essentially, parse). FormatConverter.convert(source, result);     // Now get the DOM Document object and work with it. Document doc = (Document)result.getNode(  ); 

You might have noticed something amiss about the FormatConverter class as it stands: it can actually be simplified quite a bit, as all the TrAX Source classes implement a common interface, and all the TrAX Result classes implement another interface. Now that you have an idea about what is behind the format conversion, you can simplify your helper class to that shown in Example 5-18.

Example 5-18. Simplified version of FormatConverter
 package com.oreilly.xml;     import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory;     public class FormatConverter {         private static boolean initialized = false;         private static Transformer transformer;         private static void initialize(  ) throws TransformerException {         TransformerFactory factory = TransformerFactory.newInstance(  );         transformer = factory.newTransformer(  );         initialized = true;     }         public static void convert(Source source, Result result)          throws TransformerException {         transformer.transform(source, result);     }     static {initialize();} } 

This approach is much simpler and keeps things brief.

I l @ ve RuBoard


The OReilly Java Authors - JavaT Enterprise Best Practices
The OReilly Java Authors - JavaT Enterprise Best Practices
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 96

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net