DOM(Document Object Model)是XML文档的应用程序接口,它定义了对XML文档进行随机访问与操作的方法。DOM是一个与语言无关、与平台无关的标准接口规范。利用DOM,程序开发人员可以动态地创建XML文档,遍历文档结构,添加、修改、删除文档内容,改变文档的显示方式等。可以这样说,文档代表的是数据,而DOM则代表了如何去处理这些数据。
DOM把一个XML文档映射成一个分层对象模型,而这个层次的结构,是一棵根据XML文档生成的节点树。DOM在对XML文档进行分析之后,不管这个文档有多简单或多复杂,其中的信息都会被转化成一棵对象节点树。在这棵节点树中,有一个根节点,其他所有的节点都是根节点的子节点。节点树生成之后,就可以通过DOM接口访问、修改、添加、删除树中的节点或内容了。
对DOM树的操作,主要通过以下几个接口。
1.Node接口
Node接口在整个DOM树中具有举足轻重的地位,DOM接口中有很大一部分接口是从Node接口继承过来的,例如Document(根节点)、Element(元素)、Attr(属性)、Comment(注释)、Text(元素或属性的文本内容)等接口都是从Node继承过来的。在DOM树中,Node接口代表了树中的一个节点。Node接口的常用方法如下。
- NodeList getChildNodes()
返回此节点的所有子节点的NodeList。
- Node getFirstChild()
返回此节点的第一个子节点。
返回此节点的最后一个子节点。
- Node getNextSibling()
返回此节点之后的节点。
- Node getPreviousSibling()
返回此节点之前的节点。
- Document getOwnerDocument()
返回与此节点相关的Document对象。
- Node getParentNode(
返回此节点的父节点。
- short getNodeType()
返回此节点的类型。
- String getNodeName()
根据此节点类型,返回节点名称。
- String getNodeValue()
前面已经提到,DOM中很多接口都是从Node接口继承的,所以Node接口拥有的方法这些接口都可以使用。但是这些从Node接口继承下来的接口又都各有特性,所以Node接口拥有的方法在各个子接口上的返回值含义不尽相同。例如,对于Element(元素接口)的getNodeType()的返回值为Node.ELEMENT_NODE常量,getNodeName()的返回值为标签名称,getNodeValue()的返回值为null。表4.1列出了nodeName、nodeValue 和 attributes 的值将根据接口类型的不同而不同,这对于XML解析的初学者而言是个难点,请大家务必结合后面的例子,深刻理解。
表4.1 Node子接口属性值
- String getTextContent()
返回此节点的文本内容。
根据此节点类型,设置节点值。
- void setTextContent(String textContent)
设置此节点的文本内容。
- Node appendChild(Node newChild)
将节点newChild添加到此节点的子节点列表的末尾。
- Node insertBefore(Node newChild,Node refChild)
在现有子节点refChild之前插入节点newChild。
- Node removeChild(Node oldChild)
从子节点列表中移除oldChild所指示的子节点,并将其返回。
- Node replaceChild(Node newChild, oldChild)
将子节点列表中的子节点oldChild替换为newChild,并返回oldChild节点。
2.Document接口
Document接口表示DOM树中的根节点,即对XML文档进行操作的入口节点。通过Document节点,可以访问到文档中的其他节点。Document接口的常用方法如下:
- Element getDocumentElement()
返回代表这个DOM树根节点的Element对象。
- NodeList getElementsByTagName(String tagname)
按文档顺序返回包含在文档中且具有给定标记名称的所有Element的NodeList。
3.NodeList接口
NodeList接口提供了对节点集合的抽象定义,包含了一个或多个节点(Node)的有序集合。NodeList接口的常用方法如下。
- int getLength()
返回有序集合中的第index个项。
使用DOM解析XML文档的步骤如下。
(1)创建解析器工厂,即DocumentBuilderFactory对象。
(2)通过解析器工厂获得DOM解析器,即DocumentBuilder对象。
(3)解析指定XML文档,得到DOM节点树。
(4)对DOM节点树进行操作,完成对XML文档的增删改查。
下面使用DOM对之前编写的用于存放“租车系统”车辆信息的vehicles.xml文档进行解析,并输出“租车系统”中有几种类型的车,“租车系统”中有几辆卡车,并详细输出每辆卡车的id属性及详细信息,程序运行结果如图4.8所示。
图4.8 使用DOM解析vehicles.xml
具体代码如下(需要大家认真阅读代码中的注释,理解含义):
在上面的代码中,用到了根节点、属性节点、元素节点和文本节点,它们的nodeName、nodeValue和attributes 的值含义各不相同,需要注意。
相比于DOM,SAX(Simple API for XML)是一种速度更快、更有效的解析XML文档的方法。它不需要一次性建立一个完整的DOM树,而是读取文档时激活事件进行处理。
DOM是W3C标准,提供的是标准的解析方式,但其解析效率一直不尽如人意。这是因为DOM解析XML文档时,把所有内容一次性装载入内存,并构建一个驻留在内存中的节点树。如果需要解析的XML文档过大,或者只对该文档中的一部分内容感兴趣,这种做法就会引起性能问题。