JavaWeb学习日记----XML的解析
xml的解析简介:
在学习javascript时,我们用的dom来解析heml文档,根据html的层级结构在内存中分配一个树形结构,把html的标签啊,属性啊和文本之类的都封装成对象。
比如:document对象,element对象,属性对象,文本对象,node结点对象
我们通常有两种方式来解析xml:dom和sax
dom解析方式:
其实跟html差不多的,也是根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象。
缺点:如果文件过大的话,就和造成内存溢出。
优点:可以很方便实现增删改操作。
sax解析方式:
采用事件驱动,从上到下,一行一行的解析,边读边解析。解析到某一个对象时,返回对象名称。
缺点:不能实现增删改操作
优点:不会内存溢出,可以方便实现查询操作。
解析器:
在解析xml时,需要解析器。针对dom和sax,不同的公司和组织向我们提供了不同的解析器。
sun公司: jaxp
dom4j组织: dom4j
jdom组织 : jdom
在实际开发中,dom4j用的最多
jaxp:
jaxp解析器在jdk的javax.xml.parsers包里面。针对dom和sax分别提供了解析器:
dom: documentbuilder: 解析器类
documentbuilderfactory: 解析器工厂类
sax: saxparser: 解析器类
saxparserfactory: 解析器工厂类
那么我们具体获得jaxp中的dom解析器的方法如下:
调用documentbuilderfactory.newinstance()方法得到创建dom解析器的工厂。
调用工厂对象的newdocumentbuilder()方法得到解析器对象。
调用解析器对象的parse()方法解析xml文档,该方法的参数为xml文档的url或者封装了xml路径的文件对象。即:parse(string uri) parse(file f)
示例:
// 创建解析器工厂 documentbuilderfactory documentbuilderfactory = documentbuilderfactory.newinstance(); // 获得解析器 documentbuilder documentbuilder = documentbuilderfactory.newdocumentbuilder(); // 解析目标xml文件 document document = documentbuilder.parse("src/onepiece.xml");
通过上述步骤我们就能得到代表整个文档的document对象,就可以利用dom特性对整个xml文档进行操纵了。
document接口中常用的方法:
nodelist getelementsbytagname(string tagname) 按文档顺序返回包含在文档中且具有给定标记名称的所element的 nodelist。 element createelement(string tagname) 创建指定类型的元素。 text createtextnode(string data) 创建给定指定字符串的 text 节点。
document的父接口node中常用的方法:
node appendchild(node newchild) 将节点 newchild 添加到此节点的子节点列表的末尾。 node removechild(node oldchild) 从子节点列表中移除 oldchild 所指示的子节点,并将其返回。 node getparentnode() 此节点的父节点。
string gettextcontent() 此属性返回此节点及其后代的文本内容。 void settextcontent(string textcontent) 此属性返回此节点及其后代的文本内容。
在得到的nodelist集合中有下列方法可以实现遍历:
int getlength() 列表中的节点数。 node item(int index) 返回集合中的第 index 个项。
在对document对象进行更新操作时,都是在内存中进行的。如果想要更直观地显示在xml文档中,需要进行回写操作。即:把document对象又重新写入到xml文件中。
示例:
现有一个xml文档内容如下:
<?xml version="1.0" encoding="utf-8" standalone="no"?> <海贼王> <草帽海贼团> <船长>路飞</船长> <厨师>山治</厨师> <航海士>娜美</航海士> <船医>乔巴</船医> <音乐家>贝多芬</音乐家> </草帽海贼团> <草帽海贼团> <副船长>索隆</副船长> <考古学家>罗宾</考古学家> <狙击手>乌索普</狙击手> <船工>弗兰奇</船工> </草帽海贼团> </海贼王>
需求:将第一个<草帽海贼团>下面的<音乐家>内容贝多芬改为布鲁克
代码如下:
package com.alex; import javax.xml.parsers.documentbuilder; import javax.xml.parsers.documentbuilderfactory; import javax.xml.transform.transformer; import javax.xml.transform.transformerfactory; import javax.xml.transform.dom.domsource; import javax.xml.transform.stream.streamresult; import org.w3c.dom.document; import org.w3c.dom.node; import org.w3c.dom.nodelist; /* * 将第一个<草帽海贼团>下面的<音乐家>内容贝多芬改为布鲁克 */ public class onepiecetest3 { public static void main(string[] args) throws exception { // 创建解析器 documentbuilderfactory documentbuilderfactory = documentbuilderfactory.newinstance(); documentbuilder documentbuilder = documentbuilderfactory.newdocumentbuilder(); // 解析目标xml文件 document document = documentbuilder.parse("src/onepiece.xml"); // 获得目标元素集合 nodelist list = document.getelementsbytagname("草帽海贼团"); node node = list.item(0); nodelist childnodes = node.getchildnodes(); for (int j = 0; j < childnodes.getlength(); j++) { node node2 = childnodes.item(j); string nodename = node2.getnodename(); if (nodename.equals("音乐家")) node2.settextcontent("布鲁克"); } // 回写 // 创建转换器 transformerfactory transformerfactory = transformerfactory.newinstance(); transformer transformer = transformerfactory.newtransformer(); transformer.transform(new domsource(document), new streamresult("src/onepiece.xml")); } }
修改后xml文档内容如下:
<?xml version="1.0" encoding="utf-8" standalone="no"?> <海贼王> <草帽海贼团> <船长>路飞</船长> <厨师>山治</厨师> <航海士>娜美</航海士> <船医>乔巴</船医> <音乐家>布鲁克</音乐家> </草帽海贼团> <草帽海贼团> <副船长>索隆</副船长> <考古学家>罗宾</考古学家> <狙击手>乌索普</狙击手> <船工>弗兰奇</船工> </草帽海贼团> </海贼王>
2019-04-05