Building Parser Objects


Because XMLReader is an interface, it has no constructors. Instead you use the static factory method XMLReaderFactory.createXMLReader() to retrieve an instance of XMLReader . And there are two such methods in the XMLReaderFactory class:

 public static XMLReader  createXMLReader  () throws SAXException  public static XMLReader  createXMLReader  (String  className  )  throws SAXException 

The first one returns the default XMLReader implementation class. This is specified by the org.xml.sax.driver Java system property. Parser vendors are supposed to modify this method to return an instance of their own parser in the event that this property is not set, but in practice few vendors do this. Consequently, when running a program that relies on XMLReaderFactory.createXMLReader() you may want to set the org.xml.sax.driver Java system property at the command line using the -D flag to the interpreter, as follows :

 %  java -Dorg.xml.sax.driver=   com.fully.package.qualified.ParserClass   MainClass  

If there are multiple versions of the SAX classes in your class path , then whichever one the virtual machine finds first gets to choose which XMLReader implementation class to give you. If you want a specific class (for example, org.apache. xerces.parsers.SAXParser ), then you can ask for it by fully package-qualified name using the second XMLReaderFactory.createXMLReader() method. For example, the following code asks for the Xerces parser by name:

 XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); 

If the class you request can't be located, createXMLReader() throws a SAXException . Because there's no guarantee that any particular parser is installed on any given system where your code may run, be prepared to catch and respond to this. Normally the correct response is to fall back to the default parser, like this:

 XMLReader parser;    try {     parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");   }   catch (SAXException e) {     try {       parser = XMLReaderFactory.createXMLReader();     }     catch (SAXException e) {      throw new NoClassDefFoundError("No SAX parser is available");       // or whatever exception your method is declared to throw     }   } 

Alternately, you can try multiple known parser classes until you find one that's available. The following code searches for several of the major parsers in my personal order of preference, falling back on the default parser only if none of these can be found:

 XMLReader parser;  try {// Xerces   parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); } catch (SAXException e1) {   try {// Crimson     parser = XMLReaderFactory.createXMLReader("org.apache.crimson.parser.XMLReaderImpl");   }   catch (SAXException e2) {     try {// lfred       parser = XMLReaderFactory.createXMLReader("gnu.xml.lfred2.XmlReader");     }     catch (SAXException e3) {       try {// Piccolo         parser = XMLReaderFactory.createXMLReader("com.bluecast.xml.Piccolo");       }       catch (SAXException e4) {         try {// Oracle           parser = XMLReaderFactory.createXMLReader("oracle.xml.parser.v2.SAXParser");         }         catch (SAXException e5) {           try {// default             parser = XMLReaderFactory.createXMLReader();           }           catch (SAXException e6) {             throw new NoClassDefFoundError("No SAX parser is available");               // or whatever exception your method is               // declared to throw           }         }       }     }   } } 

I use this technique in my working code; and you're more than welcome to copy it. However, because it's quite long and repetitive, in the examples in this book I'll mostly stick to one named parser and a fallback to the default.

I also occasionally see programs that use a constructor to retrieve an instance of a particular class. For example,

 XMLReader parser = new SAXParser() 

Or, worse yet,

 SAXParser parser = new SAXParser() 

This doesn't let you do anything you can't do with XMLReaderFactory.createXMLReader() . However, it does tie your code tightly to one particular parser, making it a little more difficult to change parsers at a later date. At an absolute minimum, swapping in a different parser will require an edit and a recompile. If you use XMLReaderFactory.createXMLReader() instead, users can change parsers without even having access to the source code.



Processing XML with Java. A Guide to SAX, DOM, JDOM, JAXP, and TrAX
Processing XML with Javaв„ў: A Guide to SAX, DOM, JDOM, JAXP, and TrAX
ISBN: 0201771861
EAN: 2147483647
Year: 2001
Pages: 191

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