Home arrow Java arrow Page 2 - Extension Interfaces and SAX
JAVA

Extension Interfaces and SAX


In this conclusion to a three-part article, we look at extension interfaces, XML filters, and more as they relate to the Simple API for XML (SAX). This article is excerpted from chapter four of the book Java and XML, Third Edition, written by Brett McLaughlin and Justin Edelson (O'Reilly, 2006; ISBN: 059610149X). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Author Info:
By: O'Reilly Media
Rating: 3 stars3 stars3 stars3 stars3 stars / 6
July 19, 2007
TABLE OF CONTENTS:
  1. · Extension Interfaces and SAX
  2. · Extension Interfaces
  3. · XMLFilters continued
  4. · XMLWriter

print this article
SEARCH DEVARTICLES

Extension Interfaces and SAX - Extension Interfaces
(Page 2 of 4 )

Unfortunately, most parsers donít support these extensions, so any sort of detailed coverage of them is infeasible. Icould show you how they behave under lesser-used parsers that support them, but thatís hardly helpful when you move to more main stream parsers like Apache Xerces. If you are interested in these extensions, check out the SAX Javadoc at http://www.saxproject.org/apidoc/org/xml/sax/ext/package-summary.html, and hope that by the next revision of this book, these will be more commonly supported (and then Iíll spend some time on them!).

For those who want the fullest in SAX features, you should check out AElfred2 and the GNU JAXP project, online at http://www.gnu.org/ software/classpathx/jaxp. I prefer to use Xerces for production work, but your mileage may vary.

Filters and Writers

At this point, Iwant to diverge from the beaten path. There are a lot of additional features in SAX that can really turn you into a power developer, and take you beyond the confines of ďstandardĒ SAX. In this section, Iíll introduce you to two of these: SAX filters and writers. Using classes both in the standard SAX distribution and available separately from the SAX web site (http://www.saxproject.org), you can add some fairly advanced behavior to your SAX applications. This will also get you in the mindset of using SAX as a pipeline of events, rather than a single layer of processing.

XMLFilters

First on the list is the org.xml.sax.XMLFilter class that comes in the basic SAX download, and should be included with any parser distribution supporting SAX 2. This class extends the XMLReader interface, and adds two new methods to that class, as shown in Figure 4-8.


Figure 4-8.  Extra methods defined by the XMLFilter interface 

It might not seem like there is much to say here; whatís the big deal, right? Well, by allowing a hierarchy of XMLReader s through this filtering mechanism, you can build up a processing chain, or pipeline, of events. To understand what I mean by a pipeline, you first need to understand the normal flow of a SAX parse:

  1. Events in an XML document are passed to the SAX reader.
  2. The SAX reader and registered handlers pass events and data to an application.

What developers started realizing, though, is that it is simple to insert one or more additional links into this chain:

  1. Events in an XML document are passed to the SAX reader.
  2. The SAX reader performs some processing and passes information to another SAX reader.
  3. Repeat until all SAX processing is done.
  4. Finally, the SAX reader and registered handlers pass events and data to an application.

Itís the middle two steps that create a pipeline, where one reader that performed specific processing passes its information on to another reader, repeatedly, instead of having to lump all code into one reader. When this pipeline is set up with multiple readers, modular and efficient programming results. And thatís what the XMLFilter class allows for: chaining of XMLReader implementations through filtering. Enhancing this even further is the class org.xml.sax.helpers.XMLFilterImpl , which provides a simple implementation of XMLFilter . It is the convergence of an XMLFilter and the DefaultHandler class: the XMLFilterImpl class implements XMLFilter , ContentHandler , ErrorHandler , EntityResolver , and DTDHandler , providing pass-through versions of each method of each handler. In other words, it sets up a pipeline for all SAX events, allowing your code to override any methods that need to insert processing into the pipeline.

Again, itís best to see these in action. Example 4-2 is a working, ready-to-use filter. Youíre past the basics, so Iím going to move through this rapidly.

Example 4-2.  This simple filter allows for wholesale replacement of a namespace URI with a new URI

package javaxml3;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLFilterImpl;

public class NamespaceFilter extends XMLFilterImpl {

  /** The old URI, to replace * /
  private String oldURI;

  /** The new URI, to replace the old URI with */
  private String newURI;

  public NamespaceFilter(XMLReader reader,
                        
String oldURI, String newURI) {
    super(reader);
    this.oldURI = oldURI;
    this.newURI = newURI;
 
}

  public void startPrefixMapping(String prefix, String uri)
    throws SAXException {

    // Change URI, if needed
    if (uri.equals(oldURI)) {
      super.startPrefixMapping(prefix, newURI);
    } else {
      super.startPrefixMapping(prefix, uri);
    }
  }

  public void startElement(String uri, String localName,
                           String qName, Attributes attributes)
    throws SAXException {

    // Change URI, if needed
    if (uri.equals(oldURI)) {
      super.startElement(newURI, localName, qName, attributes);
    } else {
      super.startElement(uri, localName, qName, attributes);
    }
  }

  public void endElement(String uri, String localName, String qName)
    throws SAXException {

    // Change URI, if needed
    if (uri.equals(oldURI)) {
      super.endElement(newURI, localName, qName);
    } else {
      super.endElement(uri, localName, qName);
    }
  }
}

Start out by extending XMLFilterImpl , so you donít have to worry about any events that you donít want to deal with (like DefaultHandler , youíll get no-op methods ďfor freeĒ); the XMLFilterImpl class takes care of them by passing on all events unchanged unless a method is overridden. All thatís left, in this example, is to change a namespace URI from an old one, to a new one.

If this example seems trivial, donít underestimate its usefulness. Many times in the last several years, the URI of a namespace for a specifica tion (such as XML Schema or XSLT) has changed. Rather than having to hand-edit all of my XML documents or write code for XML that I receive, this NamespaceFilter takes care of the problem for me.


blog comments powered by Disqus
JAVA ARTICLES

- Java Too Insecure, Says Microsoft Researcher
- Google Beats Oracle in Java Ruling
- Deploying Multiple Java Applets as One
- Deploying Java Applets
- Understanding Deployment Frameworks
- Database Programming in Java Using JDBC
- Extension Interfaces and SAX
- Entities, Handlers and SAX
- Advanced SAX
- Conversions and Java Print Streams
- Formatters and Java Print Streams
- Java Print Streams
- Wildcards, Arrays, and Generics in Java
- Wildcards and Generic Methods in Java
- Finishing the Project: Java Web Development ...

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials