A Better Way to Load a Parser

Although we now have a successful demonstration of SAX parsing, there is a glaring problem with our code. Let’s take a look again at how we obtain an instance of XMLReader:

try {
        // Instantiate a parser
        XMLReader parser = 
            new SAXParser(  );
            
        // Register the content handler
        parser.setContentHandler(contentHandler);
        
        // Register the error handler
        parser.setErrorHandler(errorHandler);
            
        // Parse the document
        parser.parse(uri);
        
    } catch (IOException e) {
        System.out.println("Error reading URI: " + e.getMessage(  ));
    } catch (SAXException e) {
        System.out.println("Error in parsing: " + e.getMessage(  ));
    }

Do you see anything that rubs you wrong? Let’s look at another line of our code that may give you a hint:

// Import your vendor's XMLReader implementation here
import org.apache.xerces.parsers.SAXParser;

We have to explicitly import our vendor’s XMLReader implementation, and then instantiate that implementation directly. The problem here is not the difficulty of this task, but that we have broken one of Java’s biggest tenets: portability. Our code cannot run or even be compiled on a platform that does not use the Apache Xerces parser. In fact, it is conceivable that an updated version of Xerces might even change the name of the class used here! Our “portable” Java code is no longer very portable.

What is preferred is to request an instance of a class by the name of the implementation class. This allows a simple String parameter to be changed in your source code. Luckily, ...

Get Java and XML now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.