原文出处:http://www.cnblogs.com/dongzhiquan/archive/2009/06/27/1994836.html
node 有几个子类型:Element, Text, Attribute, RootElement, Comment, Namespace等Element是可以有属性和子节点的node 。
---------------------------------------------------------
node 和Element是两个领域的概念。
NODE是相对TREE这种数据结构而言的。TREE就是由NODE组成。这个部分你可以参考离散数学的树图。
ELEMENT则是XML里的概念,<xxx>就是元素,是XML中的数据的组成部分之一。
之所以会ELEMENT和NODE会有概念上的重叠,是因为XML采用的是TREE的结构,因此你只要明白TREE的概念就明白它们的区别了。
最后,在强调一下,严格意义上说,它们是2个不同领域的概念。
---------------------------------------------------------
DOM (文档对象模型)是对 XML 数据的描述体系,它用树型结构的文档来保存 XML 数据。此外, DOM 也包括了解析、处理 XML 数据的 API 。
在开始使用 DOM 之前,首先来了解一下它的结构。 DOM 整体上的结构是一个 Composite 模式。所有的 XML 单元,无论是文档、元素还是属性、文本,在 DOM 中都是一个 Node (节点)。按照Composite 模式的定义,每个 Node 都可以包容其他的 Node ,于是很轻松地就构成了一个树型结构。
-------------------------------------------------
xml中Node和Element的区别 :
元素(Element)和结点(Node)的区别,元素是一个小范围的定义,必须是含有完整信息的结点才是一个元素,例如<div>...</div>。但是一个结点不一定是一个元素,而一个元素一定是一个结点。
---------------------------------------------------------
Attr 接口表示 Element
对象中的属性。通常该属性所允许的值定义在与文档相关的模式中。
---------------------------------------------------------
一、什么是DOMDOM是Document Object Model的缩写,是对XML文档的内容进行表示的模型。它把XML文档看作是一系列node和node间的关系,并且把每一个node都当作一个对象,所以叫文档对象模型。
DOM规范是W3C定义的,有三个Level:
l Level 1: 定义了绝大多数基础功能
l Level 2: 增加定义了namespace
l Level 3: 对各个特性有了更好的支持
DOM是与编程语言无关的,因此有多种实现,这里的都是用Java的API(其他的我也不会),用的是Sun定义的标 准JAXP(Java API for XML Parsing),而JAXP仅仅是一个接口,它是调用其他的具体解析器来实现的。此外不是用JAXP的 DOM实现还有JDOM和DOM4J。
DOM将文档中的所有都看作节点,因此定义了一个最基础的接口是Node,它的字接口包括 Element,Attr,Text等等,还包括了Document,也就是说DOM将整个文档看作是一个节点。在Node中定义了很多方法,包括了读取 节点 (getFirstChild(), getNextSibling(), getLastNode(), getChildNodes(), getNodeName(), getNodeType(), getNodeValue(), getParentNode(), getAttributes(), getOwnerDocuemt())、 修改节点 (insertBefore(), removeChild(), appendChild(), replaceChild(), setNodeValue()), 这些方法都非常常用,但是没有定义创建节点的方法,创建节点的方法是在它的子接口Document中定义的(createXXX()),也没有定义按节点 名字来得到节点的方法,这些方法是在Element和Document中定义的 (getElementById(), getElementByTagName(), 注意在这里按照名字直接得到的是Element)。
DOM在解析文档的时候按整个文档的结构生成一棵树,全部保存在内存中,这既产生了一些优点,也产生了一些缺点。优点 就是整个文档都一直在内存中,我们可以随时访问任何节点,并且对树的遍历也是比较熟悉的操作;缺点则是耗内存,并且必须等到所有的文档都读入内存才能进行 处理。
一个需要注意的地方就是,XML文档两个标签之间的空白也是这棵树的一个节点(Text节点)。
二、DOM的API1、创建Document
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("abc.xml");
创建一个文档的过程是非常固定的,三步走。在这里DocumentBuilderFactory有一些方法可以对我们的解析进行一定的控制,比如是否必须经过DTD或Schema验证有效,是否忽略注释,是否忽略namespace等等:
factory.setValidating(true);
factory.setIgnoringComments(true);
factory.setNamespaceAware(true);
2、浏览XML文档的内容
获得Document后的第一步就是获得root element,也叫document element:
Element root = doc.getDocumentElement();
这是Document最常用的方法之一,然而事实上直接调用getFirstChild()也可以得到。获得根节点后 就可以用各种各样的getXXX()方法来进行浏览。有一个重要的问题是Attr不属于任何节点的子节点,因此用 getFirstChild(),getNextSibling(),getChildNodes()是无法得到它的,必须用专用的方法 getAttributes(),getAttribute(String)单独处理。
3、修改XML文档
修改包含两方面的内容,一方面是修改已有的,另一方面是创建新的节点加入到文档中去。
修改已有的节点值,只需要浏览到目标节点,然后调用Node.setNodeValue()就可以了,对Attr来说则是调用setValue();而修改已有的节点,则用replaceChild();删除一个节点用removeChild()。
创建新节点时,正如前面所说,是用Document来创建的。创建好后就可以使用append()或 insertBefore()来插入到合适的地方。此外Attr总是比较特殊,为一个元素添加属性需要用setAttribute()方法,而删除属性则 要用removeAttribute()方法。
4、返回值NodeList和NamedNodeMap在get方法中,有些方法返回一个节点列表,最多的是NodeList,而getAttributes()返回的是NamedNodeMap,幸好两者完全像一个List,访问的方法都是item(int index)。
5、输出XML文档
前面的修改xml文档只是在内存中修改了这棵树,并没有真正影响磁盘上的文件。要真正输出到磁盘上,事实上和DOM没 什么关系,而是用FileWriter或FileOutputStream输出文档为一个文件而已。然而有一点需要注意的是,在调用 FileWriter.write()时,写的不是Document对象,而是根元素对象:
writer.write(root);
此外通常需要创建一个新的xml文档,DocumentBuilder的另一个方法是newDocument()可以创建一个新的文档,然后自然可以创建一系列的节点,并联结起来,形成一个完整的文档,最后输出。
有一点值得奇怪的是,通常我们会需要在读入一个文档后,进行了浏览,做了一些修改,然后想要把这些修改也写回到磁盘上,但是却没有直接写回原文档的方法,只能是使之输出到一个同名文档,覆盖了原来的。