jaxp解析XML之DOM解析


XML解析技术
XML解析方式分为三种一种是DOM解析一种是SAX解析

DOM思想:将整个xml加载入内存,形成围挡对象,所有对xml操作都是对内存中节点对象进行,
DOM是官方xml解析标准,同时支持解析其他各种语言

SAX解析方式的出现,因为DOM的解析方式需要对文档进行加载入内存,当文档较大的时候比较消耗资源,这时候就出现了SAX解析
SAX思想:一边解析,一边处理,一边释放资源

在JDK6中又引入了另一种StAX解析方式
是一种拉模式的xml解析方式,而SAX是一种推模式XML解析方式
推模式由服务器端为主导,向客户端发送数据,push模式
拉模式由客户端为主导,主动地向服务器申请数据,pull模式

XML解析开发包
JAXP sun官方推出的解析实现方式同时支持三种解析方式
DOM4j 开源社区框架,支持DOM解析方式
XML PULL 安卓移动设备内置,支持XML PULL解析方式

DOM支持回写
会将整个XML载入内存,以树形结构方式存储,XML比较复杂的时候,或者当你需要随机处理文档中数据的时候不建议使用

SAX/STAX
相比DOM是一种更为轻量级的方案
采用串行方法读取---文件输入流(字节,字符)读取方式
不支持过程中修改XML数据
编程较为复杂

具体使用哪种解析方式要根据实际情况来判断
1,应用程序是否必须对数据进行修改,并作为XML文档输出,则大多数情况下使用DOM
2,数据的数量过大时,SAX/STAX是更好的选择
3.如何使用数据,如果实际上只是使用一小部分数据,则使用SAX/STAX
4.性能效率,通常SAX/STAX实现比DOM要快

JAXP 开发进行XML解析
1,导包
org.w3c.dom存放DOM解析时,数据节点类
org.xml.sax存放SAX解析时的相关工具类
javax.xml.parser存放DOM和SAX的解析器
javax.xml.stream存放STAX解析时的相关类

DOM解析过程
将整个XML文档加载到内存中
工厂---解析器---解析加载---操作数据

DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();//构造工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder();//通过工厂获得解析器
Document doc=builder.parse(".xml");//对指定xml文件进行解析加载返回一个xml文档对象
NodeList nodelist=doc.getElementsByTagNmae("name");//根据名称返回一个节点列表集合
for(int i=0,i<nodelist.getLength();i++){
  Node node=nodelist.item(i);//获取节点对象
  Element e=(Element)node;将节点对象强转成标签元素对象,因为节点是一个父类,其中还具有属性节点等其他子类
  e.getNodeName();
}


Node节点常用的三个API方法
getNodeName();返回节点的名称
getNodeType();返回节点的类型//标签元素节点值为1,
getNodeValue();返回节点的值----所有元素节点的value都是null
Element标签元素节点常用方法
getAttribute(属性名);//根据属性名获取属性值
getTextContent();//获取节点内部文本内容
getFirstChild().getNodeValue();//返回第一个子节点的值,

<name>天天</name>
<name color=red>天天</name>
因为文本也是一个节点,所以对于第一句getFirstChild()获得的文本节点对象,第二句获得则是color属性节点的对象
获取文本节点对象之后通过获取节点值来获取文本内容,当然对于标签元素对象也可以通过getTesxtContent()方法获取内部文本内容。

节点对象的查询总结
标签元素节点具有承上启下的关系,所以对于节点的操作第一步都是先确定元素节点再通过相对位置去获得其他类型节点
全局查找元素节点
document.getElementsByTagName();通过标签名称获取标签元素对象数组
document.getElementById();通过标签id获得指定标签对象,只能用于带有约束的XML文档,不带有约束时不能确定ID是否是指定的ID属性还是其他数据。
相对节点位置查找节点
getFirstChild();返回这个节点的第一个子节点
getChildNodes();返回这个节点的所有子节点列表
getParentNode();返回这个节点的父节点对象
getNexrSibling();返回该节点下一个兄弟节点,
getPreviousSibling();返回该节点前一个兄弟节点。

注意属性节点与标签元素节点之间不是父子关系只是连接关系。属性节点不是任何节点的父节点或者子节点
回车换行空格也是一种节点。
<books>
<book>
<name>书本</name>
<price>18元</price>
</book>
</books>
如此处book节点对象有5个子节点对象三个回车换行节点,两个标签元素节点,他们之间是都是兄弟关系,而其中的文本内容节点与标签元素节点之间是父子关系。

更新XML文档
增加,修改,删除操作。

要进行更新首先要知道如何进行回写
Transformer类
该类中有个transform方法将document对象转换成XML文件

TransformerFactory transformerFactory=TransformerFactory.newInstance();//转换工厂
Transformer transformer=transformerFactory.newTransformer();//转换器
DOMSource domSource=new DOMSoruce(document);//通过document构造DOM源对象
StreamResult result=new StreamResult(new File(""));//建立结果文件写入流对象
transformer.transform(domSource,result);//开始转换。


这就是DOM的回写。

增加节点
1.创建节点元素对象,2,获取插入节点位置,3,将节点元素对象传入指定节点位置,4,回写XML

Element newBook=document.createElement("book");//创建<book>节点
Element newName=document.createElement("name");//创建<name>节点
newName.setTextContent("新书");//设置文本内容
newBook.appendChild(newName);//将name元素添加到book的子节点中
Element root=document.getDocumentElement();//获取根节点
root.appendChild(newBook);//在根节点添加添加子节点


最后进行回写
要注意此时是没有添加回车换行节点的,所以在回写之后的XML文档之中是没有换行的。

修改节点
1,查询获取要修改的节点对象,2,设置节点修改后的文本内容setContentText或者属性setAttribute3,回写XML
删除节点
1,查询获取要删除的节点对象,2,获取该对象的父节点对象,3通过父节点对象的remove方法删除子节点对象,4,回写
此处要注意在for循环遍历时,由于删除之后listNode节点集合长度在减少,所以要在内部进行循环变量的同步自减。

原文地址:https://www.cnblogs.com/ss561/p/4612108.html