在上面的例子中,DOMParser 的 Parse() 方法负责解析 XML 文件并生成对应的 DOM Document 对象。其中 DocumentBuilderFactory 用于生成 DOM 文档解析器以便解析 XML 文档。 在获取了 XML 文件对应的 Document 对象之后,我们可以调用一系列的 API 方便的对文档对象模型中的元素进行访问和处理。 需要注意的是调用 Element 对象的 getChildNodes() 方法时将返回其下所有的子节点,其中包括空白节点,因此需要在处理子 Element 之前对节点类型加以判断。

  可以看出 DOM 解析 XML 易于开发,只需要通过解析器建立起 XML 对应的 DOM 树型结构后便可以方便的使用 API 对节点进行访问和处理,支持节点的删除和修改等。 但是 DOM 解析 XML 文件时会将整个 XML 文件的内容解析成树型结构存放在内存中,因此不适合用 DOM 解析很大的 XML 文件。

  SAX 解析 XML

  与 DOM 建立树形结构的方式不同,SAX 采用事件模型来解析 XML 文档,是解析 XML 文档的一种更快速、更轻量的方法。 利用 SAX 可以对 XML 文档进行有选择的解析和访问,而不必像 DOM 那样加载整个文档,因此它对内存的要求较低。 但 SAX 对 XML 文档的解析为一次性读取,不创建任何文档对象,很难同时访问文档中的多处数据。

  下面是一个 SAX 解析 XML 的例子:

import org.xml.sax.Attributes;   
import org.xml.sax.SAXException;   
import org.xml.sax.XMLReader;   
import org.xml.sax.helpers.DefaultHandler;   
import org.xml.sax.helpers.XMLReaderFactory;   
 
public class SAXParser {   
 
  class BookHandler extends DefaultHandler {   
     private List<String> nameList;   
     private boolean title = false;   
    
     public List<String> getNameList() {   
        return nameList;   
     }   
     // Called at start of an XML document   
     @Override   
     public void startDocument() throws SAXException {   
        System.out.println("Start parsing document...");   
        nameList = new ArrayList<String>();   
     }   
     // Called at end of an XML document   
     @Override   
     public void endDocument() throws SAXException {    
        System.out.println("End");    
     }   
       
     /**   
      * Start processing of an element.   
      * @param namespaceURI  Namespace URI   
      * @param localName  The local name, without prefix   
      * @param qName  The qualified name, with prefix   
      * @param atts  The attributes of the element   
      */   
     @Override   
     public void startElement(String uri, String localName, String qName,   
     Attributes atts) throws SAXException {   
        // Using qualified name because we are not using xmlns prefixes here.   
        if (qName.equals("title")) {   
           title = true;   
        }   
     }   
    
     @Override   
     public void endElement(String namespaceURI, String localName, String qName)   
        throws SAXException {   
        // End of processing current element   
        if (title) {   
           title = false;   
        }   
     }   
              
     @Override   
     public void characters(char[] ch, int start, int length) {   
        // Processing character data inside an element   
        if (title) {   
           String bookTitle = new String(ch, start, length);   
           System.out.println("Book title: " + bookTitle);   
           nameList.add(bookTitle);   
        }   
     }   
          
  }   
 
  public static void main(String[] args) throws SAXException, IOException {   
     XMLReader parser = XMLReaderFactory.createXMLReader();   
     BookHandler bookHandler = (new SAXParser()).new BookHandler();   
     parser.setContentHandler(bookHandler);   
     parser.parse("books.xml");   
     System.out.println(bookHandler.getNameList());   
  }   
}