一、前言
  
  用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object Module)称为DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。
  
  JAXP接口包含了三个包:
  
  (1)org.w3c.dom W3C推荐的用于XML标准规划文档对象模型的接口。
  
  (2)org.xml.sax  用于对XML进行语法分析的事件驱动的XML简单API(SAX)
  
  (3)javax.xml.parsers解析器工厂工具,程序员获得并配置特殊的特殊语法分析器。
  
  二、前提
  
  DOM编程不要其它的依赖包,因为JDK里自带的JDK里含有的上面提到的org.w3c.dom、org.xml.sax 和javax.xml.parsers包就可以满意条件了。
  
  三、使用DOM解析XML文档
  
  我们现在来看看DOM是如何解析XML的吧!同样的,我将从一个简单的不能再简单的例子来说明DOM是如何解析XML文档的,先让我们看看XML是什么内容吧:
  
 <?xml version="1.0" encoding="gb2312"?>
 <books>
 <book email="iamzzb@tom.com">
 <name>hibernate</name>
 <price>100</price>
 <param>不错误</param>
 </book>
 <book email="iamzzb@126.com">
 <name>spring</name>
 <price>120</price>
 <param>太喜欢了</param>
 </book>
 </books>
  
简单的不能再简单了。但是该有的都有了,根元素、属性、子节点。好了,能反应问题就行了,下面来看看解析这个XML文件的Java代码吧!

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DomParse {

 public DomParse() {

  DocumentBuilderFactory domfac = DocumentBuilderFactory.newInstance();

  try {
   DocumentBuilder dombuilder = domfac.newDocumentBuilder();
   InputStream is = new FileInputStream("src/com/app.xml");
   Document doc = dombuilder.parse(is);
   Element root = doc.getDocumentElement();
   NodeList books = root.getChildNodes();

   if (books != null) {
    for (int i = 0; i < books.getLength(); i++) {
     Node book = books.item(i);
     if (book.getNodeType() == Node.ELEMENT_NODE) {
      String email = book.getAttributes().getNamedItem("email").getNodeValue();
      System.out.println(email);
      //String name2 = book.getAttributes().getNamedItem("name").getNodeValue();
      //System.out.println("name2="+name2);
      
      for (Node node = book.getFirstChild(); node != null; node = node.getNextSibling()) {
       if (node.getNodeType() == Node.ELEMENT_NODE) {

        if (node.getNodeName().equals("name")) {         
         String name = node.getFirstChild().getNodeValue();         
         System.out.println("name="+name);
        }
        if (node.getNodeName().equals("price")) {
         String price = node.getFirstChild().getNodeValue();
         System.out.println("price="+price);
        }
        if (node.getNodeName().equals("param")) {
         String param = node.getFirstChild().getNodeValue();
         System.out.println("param="+param);
        }
       }
      }
     }
    }

   }

  } catch (Exception e) {
  }
 }

 public static void main(String[] args) {

  new DomParse();

 }
}  


  四、代码解释
  
  先看看这个程序引用类:
  
  import java.io.FileInputStream;
  
  import java.io.FileNotFoundException;
  
  import java.io.IOException;
  
  import java.io.InputStream;
  
  import javax.xml.parsers.DocumentBuilder;
  
  import javax.xml.parsers.DocumentBuilderFactory;
  
  import javax.xml.parsers.ParserConfigurationException;
  
  //下面主要是org.xml.sax包的类
  
  import org.w3c.dom.Document;
  
  import org.w3c.dom.Element;
  
  import org.w3c.dom.Node;
  
  import org.w3c.dom.NodeList;
  
  import org.xml.sax.SAXException;
  
  上面那么简单的代码一看就明白了,但是为了介绍个DOM编程的大概还是来看看这个程序吧:
  
  (1)得到DOM解析器的工厂实例
  
  DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
  
  得到javax.xml.parsers.DocumentBuilderFactory;类的实例就是我们要的解析器工厂
  
  (2)从DOM工厂获得DOM解析器
  
  DocumentBuilder dombuilder=domfac.newDocumentBuilder();
  
  通过javax.xml.parsers.DocumentBuilderFactory实例的静态方法newDocumentBuilder()得到DOM解析器
  
  (3)把要解析的XML文档转化为输入流,以便DOM解析器解析它
  
  InputStream is=new FileInputStream("bin/library.xml");
  
  InputStream是一个接口。
  
  (4)解析XML文档的输入流,得到一个Document
  
  Document doc=dombuilder.parse(is);
  
  由XML文档的输入流得到一个org.w3c.dom.Document对象,以后的处理都是对Document对象进行的
  
  (5)得到XML文档的根节点
  
  Element root=doc.getDocumentElement();
  
  在DOM中只有根节点是一个org.w3c.dom.Element对象。
  
  (6)得到节点的子节点
  
  NodeList books=root.getChildNodes();
  
  for(int i=0;i<books.getLength();i++){
  
  Node book=books.item(i);
  
  }
  
  这是用一个org.w3c.dom.NodeList接口来存放它所有子节点的,还有一种轮循子节点的方法,后面有介绍
  
  (7)取得节点的属性值
  
  String email=book.getAttributes().getNamedItem("email").getNodeValue();
  
  System.out.println(email);
  
  注意,节点的属性也是它的子节点。它的节点类型也是Node.ELEMENT_NODE
  
  (8)轮循子节点
  
for (Node node = book.getFirstChild(); node != null; node = node.getNextSibling()) {
if (node.getNodeType() == Node.ELEMENT_NODE) {

if (node.getNodeName().equals("name")) {
String name = node.getFirstChild().getNodeValue();
System.out.println("name="+name);
}
if (node.getNodeName().equals("price")) {
String price = node.getFirstChild().getNodeValue();
System.out.println("price="+price);
}
if (node.getNodeName().equals("param")) {
String param = node.getFirstChild().getNodeValue();
System.out.println("param="+param);
}
}
}
  
这段代码的打印输出为:
iamzzb@tom.com
name=hibernate
price=100
param=不错误
iamzzb@126.com
name=spring
price=120
param=太喜欢了
  
注意:  
String name=node.getNodeValue();  是一个空值。而  
String name1=node.getFirstChild().getNodeValue(); 才是真正的值,这是因为DOM把<name>hibernate</name>也当作是两层结构的节点.