`
wufei1310
  • 浏览: 22805 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论
阅读更多


本文介绍了DOM(文档对象模型)的结构和常规使用方法。通过本文,读者可以学会用DOM来对XML文档进行常见的处理。本文不讨论DOM的设计和实现技巧。

关键词:

    XML DOM

概述
DOM(文档对象模型)是对XML数据的描述体系,它用树型结构的文档来保存XML数据。此外,DOM也包括了解析、处理XML数据的API。

在开始使用DOM之前,首先来了解一下它的结构。DOM整体上的结构是一个Composite模式。所有的XML单元,无论是文档、元素还是属性、文本,在DOM中都是一个Node(节点)。按照Composite模式的定义,每个Node都可以包容其他的Node,于是很轻松地就构成了一个树型结构。举一个简单的例子,下面的XML文档

<Book>

<Title>Effective C++</Title> 

<Author>

  <Name>Scott Meyers</Name> 

  <Gender>Male</Gender> 

  <Nationality>USA</Nationality> 

  </Author>

  <Publisher>Addison-Wesley</Publisher> 

  </Book>


在DOM中的存储形式就会是这样:



既然已经了解了DOM文档的结构,下面就该学习如何操作DOM文档了。对于这样一个树型结构,比较重要的操作有文档生成、文档遍历、节点内容的处理(读取、修改等等)、节点本身的操作(插入、删除、替换等等)以及文档的序列化。下面,我们将逐个学习这些操作。

DOM文档的生成
用DOM处理XML数据,首先需要以下三个步骤:

1.       创建DocumentBuilderFactory。该对象将创建DocumentBuilder。

2.       创建 DocumentBuilder。 DocumentBuilder将对输入实际进行解析以创建Document对象。

3.       解析输入的XML,创建Document对象。

DocumentBuilderFactory是一个Singleton,所以不能直接new出来,应该调用DocumentBuilderFactory.newInstance()来得到DocumentBuilderFactory的实例。此外,DocumentBuilderFactory也是一个对象工厂(从名字就能看出),可以用它来创建DocumentBuilder。

通常会使用DocumentBuilder的parse方法返回一个Document对象(需要插一句:Document只是一个接口,用javax.xml.parsers.DocumentBuilder的parse方法得到的实际上是org.apache.crimson.tree.XmlDocument对象)。parse方法接受很多输入参数,包括File、InputStream、InputSource、String型的URI等等。parse方法会把输入源进行解析,在内存中生成一个DOM的树型结构——Document对象。

上面这三个步骤的常用代码如下:

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."); }

parse方法可能会抛出IOException或者SAXException,分别表示输入异常和解析异常。

在创建DocumentBuilder之前,可以为DocumentBuilder设置一些参数,调节它在生成Document时的行为方式。可控的参数包括:

l        setCoalescing:确定解析器是否将 CDATA 节点转成文本,并将 CDATA 节点与其周围的文本节点合并(如果合适)。缺省值是 false。

l        setExpandEntityReferences:确定是否扩展外部实体引用。如果为 true,则将外部数据插入文档。缺省值是 true。

l        setIgnoringcomments:确定是否忽略文件中的注释。缺省值是 false。

l        setIgnoringElementContentWhitespace:确定是否忽略元素内容中的空白(类似于浏览器处理 HTML 的方式)。缺省值是 false。

l        setNameSpaceAware:确定解析器是否注意名称空间信息。缺省值是 false。

l        setValidating:缺省情况下,解析器将不验证文档。将该参数设置为 true 以打开验证。

设置参数的语句如下:
   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

   dbf.setValidating(true);

   DocumentBuilder db = dbf.newDocumentBuilder();

DOM文档的遍历
DOM采用了Composite模式。Node类是所有XML单元的基类,Element、Attr、Document等等都是Node的派生类。每个Node都可以包容其他的Node,也可以包容文本格式的内容。所以,DOM文档的遍历相当简单。

首先要获取文档的根节点。用Document.getDocumentElement()方法可以得到一个Element类型的对象,它就是文档的根节点。对于一个HTML文档,getDocumentElement()方法得到的就是<html>节点。

只要得到根节点,就可以用Node.getChildNodes()方法得到该节点的所有直接子节点,从而遍历整个树型结构。另外,可以用Node.hasChildNodes()方法判断一个节点是否叶节点,从而得到遍历算法的结束条件。getChildNodes()方法的返回值是NodeList对象,NodeList有两个方法:int getLength()和Node item(int),可以使用这两个方法来安全地访问其中的每个元素。

上面这种方法是深度优先的遍历(采用迭代算法),还有一种方法是广度优先的遍历算法,要使用的方法是getFirstChild()(获取第一个孩子节点)和getNextSibling()(获取下一个兄弟节点)。

处理元素的内容
首先必须搞清楚“节点(node)”和“元素(element)”的概念:在DOM中节点和元素不是等价的。“元素”是指一对标记(tag)及其内部包含的字符串值的总和,例如下面这就是一个元素:

<Country>
China
</Country>

但是它却不是一个节点,而是两个。第一个节点是<Country>节点,它的值是null;第二个节点是一个文本节点(节点名是#text),它的值是"China\n"。文本节点是<Country>节点的子节点。

所以,要处理一个元素的内容时,需要两个步骤:

1.       找到代表该元素的节点;

2.       处理该节点的第一个子节点;

只要知道某个元素的名称,就可以用Element.getElementsByTagName(String name)方法来找到所有代表该元素的节点。getElementsByTagName方法会自动遍历整个树型结构,将找到的节点全部保存在一个NodeList中返回。由于DOM的树型结构是建立在内存中的,所以这个操作不会太慢。找到节点之后,用Node.getFirstChild()方法就可以得到代表该元素值的文本节点,用Node.setNodeValue(String)方法就可以修改节点的值。

处理其他类型节点的内容
如果要访问的节点是属性节点(Node.getNodeType()==ATTRIBUTE_NODE),则可以通过getAttributes()方法获得节点中所有的属性。getAttributes方法会返回一个NamedNodeMap型的对象,这是一个名-值映射表,可以通过String型的名称来随机访问,也可以通过int型的顺序号来顺序访问。Attr类(属性节点)有getValue()和setValue()两个accessor,用于访问属性的值。

节点共有12种不同的类型,这里只介绍了元素节点和属性节点这两种最常用的,其他的就要自己查帮助了。Node有一个getNodeType()方法,会返回short型值,从而判断一个对象的真实类型,起到RTTI的作用。下面是getNodeType()方法所有可能的返回值:
    public static final short ELEMENT_NODE                                 = 1;

    public static final short ATTRIBUTE_NODE              = 2;

    public static final short TEXT_NODE                              = 3;

    public static final short CDATA_SECTION_NODE                = 4;

    public static final short ENTITY_REFERENCE_NODE           = 5;

    public static final short ENTITY_NODE                           = 6;

    public static final short PROCESSING_INSTRUCTION_NODE = 7;

    public static final short COMMENT_NODE                      = 8;

    public static final short DOCUMENT_NODE                     = 9;

    public static final short DOCUMENT_TYPE_NODE             = 10;

    public static final short DOCUMENT_FRAGMENT_NODE      = 11;

    public static final short NOTATION_NODE               = 12;


节点的处理
对于树型数据结构,常见的节点处理就是节点的插入、删除和替换。DOM为这些操作提供了非常简单易用的API。

插入节点可以用Node.appendChild(Node),也可以用Node.insertBefore(Node newChild, Node refChild);删除节点可以用Node.removeChild(Node oldChild);替换节点可以用Node.replaceChild(Node newChild, Node oldChild)。DOM会自动调整树型结构,删除、替换的操作还会返回oldChild这个节点,非常方便。

文档(Document)也是一个节点(Node),所以也可以把节点直接插入到文档中。不过要注意:只有该文档创建出的节点才能插入到该文档中,否则会引发WRONG_DOCUMENT_ERR异常。创建节点使用Document.createXxxx方法。可以用cloneNode(boolean deep)方法来克隆一个节点,用boolean型的参数决定是否深度拷贝,但是克隆出的节点也不能插入别的文档中。另外,可以用Document.importNode(Node importedNode, boolean deep)方法来引入别的文档中的节点。

需要处理元素的属性时,可以用Element.setAttributeNode(Attr newAttr)来插入属性,用Element.removeAttribute(String name)来删除不需要的属性。如果属性有同名的,可以用Element. removeAttributeNode(Attr oldAttr)来指定删除某一个属性节点。

文档的序列化
每个Element都覆盖了toString方法,所以只要指定某一个Element作为根,再调用它的toString方法,它就会递归得到其下的整个树型结构,并转换成String型对象。只要把这个String型对象输出到指定的设备上,就可以得到XML文档,非常方便。下面这段代码会生成一个新的HTML文档(HTML可以说是XML的子集),并在标准输出设备上输出。

Document newdoc = null;

try {

   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

    DocumentBuilder db = dbf.newDocumentBuilder();

    newdoc = db.newDocument();       

} catch(Exception e){};

Element head = newdoc.createElement("Head");

Element title = newdoc.createElement("Title");

title.appendChild(newdoc.createTextNode("Document created by DOM"));

head.appendChild(title);

Element body = newdoc.createElement("Body");

body.appendChild(newdoc.createTextNode("This is a test document"));

 

Element newroot = newdoc.createElement("Html");

newroot.appendChild(body);

newroot.insertBefore(head, body);

 

newdoc.appendChild(newroot);

System.out.println(newroot);


总结
DOM在内存中生成树型结构来处理XML数据,在处理速度和方便性上有优势,但是比较耗存储空间。如果XML文档比较大的话,解析过程可能会需要比较长的时间
分享到:
评论

相关推荐

    DOM4J jar包 xml解析 所有的dom4j-1.6.1 dom4j-2.0.2 dom4j-2.1.1包 导入直接使用

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活且高效的API,使得XML的解析、创建、修改和查询变得简单。DOM4J的名字来源于“Document Object Model for Java”,它采用面向对象的设计思想,提供了对...

    firefox DOM Inspector 火狐 dom 查看器插件 天涯浪子

    DOM Inspector是Mozilla Firefox的一个扩充套件,官方中文版上称之为DOM观察器,在安装Mozilla Firefox时,可以在自订安装中选择是否安装DOM Inspector,如果在安装Mozilla Firefox时没有选择自订安装以安装DOM ...

    dom4j_dom4j1.6.1安装包_

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活、高效的API,使得XML的解析、创建、查询和修改变得更为简单。在本文中,我们将深入探讨DOM4J 1.6.1版本的安装及其在Maven项目中的应用。 首先,DOM4J...

    xml 三种解析方式dom,sax,dom4j

    为了处理XML文档,有三种主要的解析方式:DOM、SAX和DOM4J。每种方法都有其特点和适用场景,下面将详细介绍这三种解析方式。 1. DOM(Document Object Model) DOM解析器将整个XML文档加载到内存中,构建一个树形...

    使用dom4j 和本地dom 解析xml 文件

    在Java中,解析XML文件是常见的任务,通常有DOM(Document Object Model)和DOM4J两种方式。下面我们将详细探讨这两种解析方法。 DOM解析方式是将整个XML文件加载到内存中,形成一棵DOM树,每个节点代表XML文档的一...

    dom4j_1.6.1.jar dom4j_2.1.0.jar

    标题提及的"dom4j_1.6.1.jar"和"dom4j_2.1.0.jar"是两个不同版本的DOM4J库的Java档案文件,DOM4J是一个非常流行的Java XML API,用于处理XML文档。这两个版本的差异在于功能、性能优化和可能存在的bug修复。描述中...

    dom4j-1.6.1 与 dom4j-2.0.0-ALPHA

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活、高效的API,使得XML的解析、创建、修改和查询变得简单。这次我们有两个版本的DOM4J库:1.6.1和2.0.0-ALPHA。这两个版本在功能、性能和API设计上都有所...

    XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较,超详细

    常见的 XML 解析器有 DOM、SAX、JDOM 和 DOM4J 等。每种解析器都有其特点和优缺,选择合适的解析器对应用程序的性能和开发效率有很大影响。 1. DOM 解析器 DOM(Document Object Model)是 W3C 官方标准,用于表示...

    DOM和BOM的使用

    DOM 和 BOM 的使用 DOM(Document Object Model)和 BOM(Browser Object Model)是前端开发中两个基础概念。DOM 是一个文档对象模型,它将 HTML 文档抽象为一个树形结构,允许开发者通过 JavaScript 操作文档的...

    dom4j1.1-1.6.1.rar

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活且高效的API,使得XML的解析、创建、修改和查询变得简单。DOM4J的名字来源于“Document Object Model for Java”,但它并不仅仅是一个DOM实现,它还包含...

    dom4j 2.1.1

    DOM4J 2.1.1 是一个针对Java平台的高效、开源的XML处理库,其全称为“Document Object Model for Java”。这个库提供了一系列强大的API,使得开发人员能够轻松地解析、创建、修改和操作XML文档。XML(eXtensible ...

    dom4j解析xml文件的压缩包

    DOM4J是一个强大的Java库,专门用于处理XML文档。它提供了灵活且高效的API,使得XML的解析、创建、查询和修改变得简单。这个压缩包包含了DOM4J的完整版本,适用于那些希望在Java项目中使用DOM4J进行XML操作的开发者...

    谷歌获取网页dom的插件

    在IT领域,尤其是在Web开发和数据抓取方面,"谷歌获取网页DOM的插件"是一种非常实用的工具。DOM(Document Object Model)是HTML和XML文档的结构化表示,它将网页内容作为树形结构处理,使得我们可以方便地通过...

    dom4j-2.1.1-API文档-中英对照版.zip

    赠送jar包:dom4j-2.1.1.jar; 赠送原API文档:dom4j-2.1.1-javadoc.jar; 赠送源代码:dom4j-2.1.1-sources.jar; 赠送Maven依赖信息文件:dom4j-2.1.1.pom; 包含翻译后的API文档:dom4j-2.1.1-javadoc-API文档-...

    dom4j-2.0.3.zip

    《深入解析DOM4J——基于Java的XML处理框架》 DOM4J,作为一个强大的Java XML API,是处理XML文档的主流工具之一。它提供了一套简单而高效的方式来操作XML文档,包括读取、写入、修改和遍历XML结构。在Java开发中,...

    DOM4J 的使用

    DOM4J 的使用 DOM4J 是一个开源的 XML 解析包,由 dom4j.org 出品,应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM、SAX 和 JAXP。DOM4J 的主要特点是使用大量的接口,所有主要接口都在 org.dom4j 里面定义...

    simple_html_dom,php下的html文件DOM解析库

    3. **遍历DOM**:可以轻松地遍历DOM树,获取元素、属性等信息。 4. **修改DOM**:可以添加、删除、修改HTML元素及其属性。 5. **提取数据**:支持提取文本、HTML、属性值等数据。 三、基本用法 1. **加载HTML**...

    解决vue页面DOM操作不生效的问题

    在Vue框架中,页面动态更新是非常常见的需求,但有时候开发者可能会遇到在页面上进行DOM操作不生效的问题。这种情况通常发生在某些数据更新之后,但直接进行DOM操作时,并没有取得预期效果。Vue使用的是虚拟DOM...

    dom4j-2.1.1-API文档-中文版.zip

    赠送jar包:dom4j-2.1.1.jar; 赠送原API文档:dom4j-2.1.1-javadoc.jar; 赠送源代码:dom4j-2.1.1-sources.jar; 赠送Maven依赖信息文件:dom4j-2.1.1.pom; 包含翻译后的API文档:dom4j-2.1.1-javadoc-API文档-...

Global site tag (gtag.js) - Google Analytics