Skip to main content

Simplifying the JAXP API

Posted by spericas on December 15, 2006 at 7:43 AM PST

One of the complains about the JAXP API that we are hearing (rather loudly!) is number of lines of code that are needed to implement a simple task: you need to instantiate a factory, create an instance from the factory, wrap your parameters in Sources and Results and finally carry out the task. Ah, and don't forget to catch all those exceptions or your code won't even compile. Is all the complexity of current API really necessary?

Well, as usual the answer depends on the application, but for a large set of applications all this complexity is certainly unnecessary. For these kind of applications, using the all defaults provided by JAXP is enough, and letting the exceptions unwind the stack (possibly aborting the application's execution) is just fine too.

For the sake of this discussion, let us assume that our application needs to carry out the following steps: (i) validate test.xml against test.xsd, (ii) transform test.xml to produce test-out.xml and finally query test-out.xml using an XPath expression. In JAXP 1.4, the code would look something like this:

 public String getAppResult() {
     try {
         SchemaFactory sf =
         Schema s = sf.newSchema(new File("schema.xsl"));
         Validator v = s.newValidator();
         v.validate(new StreamSource("test.xml"));

         TransformerFactory tf = TransformerFactory.newInstance();
         Transformer t = tf.newTransformer(
                 new StreamSource("test.xsl"));
         t.transform(new StreamSource("test.xml"),
                 new StreamResult("test-out.xml"));

         XPathFactory xf = XPathFactory.newInstance();
         XPath xpath = xf.newXPath();
         return xpath.evaluate("//foo[1]", new InputSource("test-out.xml"));
     catch (SAXException e) {
         // Validation problems
     catch (IOException e) {
         // Unable to find schema language
     catch (TransformerConfigurationException e) {
         // Problems while configuring the transformer
     catch (TransformerException e) {
         // Problems during transform
     catch (XPathExpressionException e) {
         // Problems parsing/evaluating XPath expression

Naturally, it may be unnecessary to catch each and every exception that may be thrown in this method; we could have caught an arbitrary Exception if we weren't planning on doing anything special in each case, but bear with me as I try to make a point.

So why does this simple task take so many lines of code? And why is it necessary to create all these objects? This is necessary due to: (i) the use of the factory pattern (ii) the number of options supported by the API (iii) the need to wrap arguments in Sources and Results and (iv) all those checked exceptions.

As part of, we are currently exploring the support for a simpler, higher-level API to make JAXP easier to use. Of course, this new API would not replace, but simply complement the existing API. The same example above could look like this using the new API:

 public String getAppRsult() {
     new Validator("test.xsd").validate("test.xml");
     new Transformer("test.xsl").transform("test.xml", "test-out.xml");
     return new XPath("//foo[1]").evaluate("test-out.xml");

More readable, right? We think so. Note that there isn't a JSR for a yet; at this point, we are simply brainstorming about how to improve the API, and ease of use is one the hot topics at the moment. If you are interested in participating in these discussions, subscribe to and send us your suggestions!

Related Topics >>