DOM 解析 XML 资料

DOM 解析 XML 文件在解析 XML 文档时,通常是利用现有的 XML 解析器软件对 XML 文档进行分析,而应用程序则

DOM 解析 XML 文件
在解析 XML 文档时,通常是利用现有的 XML 解析器软件对 XML 文档进行分析,而应用程序则通过解析器提供的 API 接口得到 XML 数据。目前几乎所有的解析器都对两套标准的 API 提供了支持,他们是 DOM 和 SAX 。
    今天在传智播客的课堂上,我们学习了如何用 DOM 来解析 XML 文件,以下是我的总结。


--------------------------------------------
1. DOM 概述:
<1> DOM 是独立于程序语言的, W3C 组织以 IDL(Interface Definition Language, 接口定义语言) 的形式定义了 DOM 中的接口。
<2> 某种程序语言要实现DOM,需要将 DOM 接口转换为本语言中的对应结构。
--------------------------------------------
2. DOM 结构模型:
<1> DOM 中的核心概念是节点。 DOM 在解析 XML 文档时,将组成 XML 文档的各个部分(元素,属性,文本等)映射为一个对象,这个对象就是一个节点。
<2> 在内存中,这些节点形成一棵文档树。整棵树也是一个节点,树中的每一个子节点也是一棵树(子树)。
<3> DOM 就是对一棵树的一个对象表示,通过访问树中的节点来存取 XML 文档的内容。
<4> DOM 定义了一个 Node 接口,用于表示文档树中的一个节点。从这个接口派生处更多的具体的接口:表示整个文档的 Document 对象,表示 XML 文档中元素的 Element 接口,表示属性元素的 Attr 接口等。
--------------------------------------------

3. DOM 中的节点类型:
XML 中最常见的节点类型是:文档,元素,文本和属性,在 DOM API 中对应的接口是: Document, Element, Text 和 Attr。
<1> 文档节点:
a. 文档节点是文档树的根节点,也是文档中其他所有节点的父节点。
b. 文档节点并不是 XML 文档的根元素,因为在 XML 文档中,处理指令,注释等内容可以出现在根节点之外,所以在构造 DOM 树时,根元素并不适合作为根节点,而作为文档节点的子节点。
c. 在 DOM API 中根节点是通过 org.w3c.dom.Document 接口来表示的。
d. 为了得到 XML 文档的根元素, 在 Document 接口中可以调用如下方法: Element getDocumentElement();
<2> 元素节点:
a. 元素节点表示了 XML 文档中的元素。
b. 元素拥有子元素,文本节点或两者的组合。
c. 元素节点也是唯一能够拥有属性的节点类型。
d. 在 DOM API 中,元素节点是通过 org.w3c.dom.Element 接口定义的。
<3> 文本节点:
a. 文本节点是只包含文本内容的节点,也可以只包含空白。
b. 在文档树中,元素和属性的文本内容都是由文本节点来表示的。
c. 在 DOM API 中,文本节点是由 org.w3c.dom.Text 接口来表示的。
<4> 属性节点:
a. 属性节点代表了元素中的属性。
b. 在 DOM API 中,属性节点通过 org.w3c.dom.Attr 接口来表示。
c. 因为属性实际上是附属于元素的,所以属性节点不是元素的子节点,而不作为单独的节点在文档树中出现。


--------------------------------------------

4. DOM 解析 XML 文档的步骤:
<1> 调用 DocumentBuilderFactory.newInstance() 方法得到 DOM 解析器工厂类实例。
<2> 调用解析器工厂实例类的 newDocumentBuilder() 方法得到 DOM 解析器对象。
<3> 调用 DOM 解析器对象的 parse() 方法解析 XML 文档得到代表整个文档的 Document 对象。


--------------------------------------------

5. 以下是用 DOM 解析一个 XML 文档的代码示例:
<1> XML 文档中的内容如下:
<?xml version="1.0" encoding="GB2312"?>
<china>
<province name="河北省">
  <city>石家庄</city>
  <city>邯郸</city>
  <city>唐山</city>
  <city>张家口</city>
  <city>廊坊</city>
</province>
<province name="辽宁省">
  <city>沈阳</city>
  <city>大连</city>
  <city>鞍山</city>
  <city>抚顺</city>
  <city>铁岭</city>
</province>
<province name="山东省">
  <city>济南</city>
  <city>青岛</city>
  <city>威海</city>
  <city>烟台</city>
  <city>潍坊</city>
</province>
</china>
<2> 下面是解析的过程:
  //1. 得到 DocumentBuilderFactory 对象, 由该对象可以得到 DocumentBuilder 对象
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 
  //2. 得到 DocumentBuilder 对象, 由该对象可以得到 Document 对象
  DocumentBuilder db = dbf.newDocumentBuilder();
 
  //3. 得到代表整个 xml 文档的 Document 对象
  Document doc = db.parse(new FileInputStream("cities.xml"));
 
  //4. 得到 "根节点" 既  Document 对象的第一个子节点(最后一个子节点)
  Node rootNode = doc.getFirstChild();
 
  //5. 把 4 得到的 Node 强转为 Element 类型
  Element rootElement  = (Element) rootNode;
  System.out.println("<" + rootElement.getNodeName() + ">");
 
  //6. 得到 "根节点" 的所有 province 子节点   
  NodeList provinceNodes = rootElement.getElementsByTagName_r("province");

  //7. 对 6 得到的 NodeList 进行遍历
  for(int i = 0; i < provinceNodes.getLength(); i++){

   //7.1 把遍历后的每一个元素强转成 Element 类型
   Element provinceElement = (Element) provinceNodes.item(i);
  
   //7.2 得到 7.1 得到的 节点的 name 属性节点
   Attr nameAttr = provinceElement.getAttributeNode("name");
  
   System.out.println("\t<" + provinceElement.getNodeName() +
    "  " +
    nameAttr.getNodeName() + "=" + nameAttr.getNodeValue() + 
    ">");

   //7.3 得到 7.1  节点的所有 "city" 子节点
   NodeList cityNodes = provinceElement.getElementsByTagName_r("city");
  
   for(int j = 0; j < cityNodes.getLength(); j++){
    Element cityElement = (Element) cityNodes.item(j);
    System.out.println("\t\t<" + cityElement.getNodeName() + ">" +
      cityElement.getFirstChild().getNodeValue() +
      "</" + cityElement.getNodeName() + ">");
   }
  
   System.out.println("\t</" + provinceElement.getNodeName() + ">");
  }
 
  System.out.println("</" + rootElement.getNodeName() + ">");
}
本文章转载自http://blog.sina.com.cn/s/blog_5de48f8b0100daso.html