君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

DOM基础

在开始使用 DOM 之前,了解它实际表示什么是值得的。DOM Document 是以层次结构组织起来的节点,或信息片段,的集合。这种层次结构允许开发 者浏览树来查找特定信息。通常,分析结构需要在完成任何工作之前装入整个 文档并且装入层次结构。

由于 DOM 是基于信息的层次结构,因此它被称为是基于树的。

对于极其大的文档,装入整个文档并对该文档进行解析会很慢且占用大量资源, 所以要用其它方式来处理数据。一些基于事件的模型,如 Simple API for XML(SAX),是工作在数据流之上,在数据流经过时对其进行处理。基于事件 的 API 消除了在内存中构建数据树的需要,但它不允许开发者实际更改原始 文档中的数据。

另一方面,DOM 还提供了一个 API,该 API 允许开发者为创建应用程序而在树的任何地方添加、编辑、移动或除去节点。

 

DOM 基本的节点类型

XML 中最常见的节点类型:

  1. Node: DOM 基本的数据类型。
  2. Element: 您将最主要处理的对象是 Element。
  3. Attr: 代表一个元素的属性。
  4. Text: 一个 Element 或 Attr 的实际内容。
  5. Document: 代表整个 XML 文档。一个 Document 对象通常也被称为一棵 DOM 树。

较不常见的节点类型:CData、注释、处理指令和文档片段:

  • CData:“字符数据”的缩写
  • 注释:注释包含有关数据的信息,通常应用程序会忽略它们。
  • 处理指令:PI 是专门针对应用程序的信息。
  • 文档片段:为了形成良好的格式,文档只能有一个根元素。有时,必须临时创建几组元素,这些元素不是满足需求所必要的。

文档片段类似于这样:

      <item instock="Y" itemid="SA15">
         <name>Silver Show Saddle, 16 inch</name>
         <price>825.00</price>
         <qty>1</qty>
      </item>
      <item instock="N" itemid="C49">
         <name>Premium Cinch</name>
         <price>49.00</price>
         <qty>1</qty>
      </item>

 

 

解析文档的三步过程

为了使用 XML 文件中的信息,必须解析该文件以创建 Document 对象。

Document 对象是一个接口,所以不能直接实例化;相反,应用程序一般使用 factory。确切的过程随实现的不同而不同,但想法是相同的。在示例 JAXP 环境中,解析文件是一个三步过程:

  1. 创建 DocumentBuilderFactory。该对象将创建 DocumentBuilder。
  2. 创建 DocumentBuilder。 DocumentBuilder 将实际进行解析以创建 Document 对象。
  3. 解析该文件以创建 Document 对象。

如果需要,在不必更改代码的情况下,JAXP 允许插进不同的解析器。让我们继续,开始构建应用程序。

 

基本的应用程序

从创建基本的应用程序,名为 OrderProcessor 的类开始。

 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import java.io.File;
 import org.w3c.dom.Document;
 public class OrderProcessor {
   public static void main (String args[]) {
      File docFile = new File("orders.xml");
      Document doc = null;      
      try {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
         doc = db.parse(docFile);
						
      } catch (Exception e) {
         System.out.print("Problem parsing the file.");
      }
   }
 }

 

首先,Java 导入必要的类,然后创建 OrderProcessor 应用程序。在本教程中的这个示例将只处理一个文件,所以为简短起见,该应用程序包含对它的直接引用。

应用程序在 try-catch 块外部定义了 Document 对象,以便在后面使用该对象。try-catch 使您能执行可能会抛出异常的一些操作,这样不会危及整个应用程序。如果异常抛出,则应用程序简单地执行相应的 catch 代码。

在 try-catch 块内部,应用程序创建 DocumentBuilderFactory,然后使用它来创建 DocumentBuilder。最后,DocumentBuilder 解析该文件以创建 Document。

 

DOM 常用方法

  1. Document.getDocumentElement() 
    返回文档的根(root)元素。
  2. Node.getFirstChild() and Node.getLastChild() 
    返回给定 Node 的第一个子女。
  3. Node.getNextSibling() and Node.getPreviousSibling() 
    这些方法返回下一个或前一个给定 Node 的同胞。
  4. Node.getAttribute(attrName) 
    对给定的 Node,返回给定名称的属性。例如,如果您要获得名为 id 属性 的对象,可调用 getAttribute("id")。
 

编辑文档

  1. 更改节点数据 
    Node.setNodeValue(elemValue);
    	
  2. 添加节点 
    String totalString = new Double(total).toString(); 
    Node totalNode = doc.createTextNode(totalString);  
    //Document 对象创建新的文本节点,该节点带有作为值的 totalString
    
    Element totalElement = doc.createElement("total"); 
    //创建新元素 total
    
    totalElement.appendChild(totalNode);				
    // 将节点添加到新的 total 元素。
    
    thisOrder.insertBefore(totalElement, thisOrder.getFirstChild()); 
    //将新元素添加到 Document,指定新的 Node,然后指定新 Node 在 Node 之前
    	
  3. 除去节点 
    Node deadNode = thisOrderItem.getParentNode().removeChild(thisOrderItem);
    	
  4. 替换节点 
    Element backElement = doc.createElement("backordered");	
    //创建新元素 backordered
    
    Node deadNode = 
    thisOrderItem.getParentNode().replaceChild(backElement,thisOrderItem);
    	
  5. 创建和设置属性 
    Element backElement = doc.createElement("backordered");	
    //创建新元素 backordered
    
    backElement.setAttributeNode(doc.createAttribute("itemid"));
    //创建新属性 itemid
    
    String itemIdString = thisOrderItem.getAttributeNode("itemid").getNodeValue();
    //取得thisOrderItem的属性itemid的值
    
    backElement.setAttribute("itemid", itemIdString);
    //设置backElement的属性item的值,可以省略createAttribute
    
    Node deadNode = 
    thisOrderItem.getParentNode().replaceChild(backElement,thisOrderItem);
    	
  6. 除去属性 
    Element thisOrder = (Element)orders.item(orderNum);
    Element customer = (Element)thisOrder.getElementsByTagName("cusomertid").item(0);
    customer.removeAttribute("limit");
    //去除属性limit
    	

 

关于作者

IBM has authored this article

posted on 2013-05-15 18:38  刺猬的温驯  阅读(179)  评论(0编辑  收藏  举报