XML——XML解析之DOM
1.XML编程XML编程,就是对XML文件进行crud操作。 那么为什么要用java或者C/C++对XML进行crud操作呢? w3C组织为了大家解析XML方便,定义了一套规范(API) 1.1.XML解析技术介绍1.XML解析分为:dom解析和sax解析
SAX解析采用事件驱动模型边读边解析:从上到下一行一行解析,解析到某一元素,调用相应的解析方法。 不同的公司和组织提供了针对DOM和SAX两种方式的解析器:
其中的JASP是J2SE的一部分,它分别针对DOM和SAX提供了DOM和SAX解析器。 在这里也主要介绍三种解析:dom、sax和dom4j 1.2.JAXP介绍Sun公司提供了Java API for XML Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。 JAXP开发包是J2SE的一部分,它由javax.xml、org.w3c.dom、org.xml.sax包及其子包组成 在javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的DOM或SAX的解析器对象。 2.JAXP之DOM解析2.1.XML DOM节点树首先说明JAXP解析XML的DOM对象的原理,XML DOM把XML文档视为一颗节点树(node-tree),树中的所有节点彼此之间都有关系。可通过这棵树访问所有的节点。可以修改或者删除它们的内容,也可以创建新的元素。 比如,现在的XML文档如下(该例子来自w3cschool在线教程): <bookstore>
<book category="children">
<title lang="en">Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
<book category="web" cover="paperback">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="web">
<title lang="en">XQuery Kick Start</title>
<author>James McGovern</author>
<author>Per Bothner</author>
<author>Kurt Cagle</author>
<author>James Linn</author>
<author>Vaidyanathan Nagarajan</author>
<year>2003</year>
<price>49.99</price>
</book>
</bookstore>
这棵树从根节点开始,在树的最低层级向文本节点长出枝条: 【要知道的几个知识点】: 2.2.获得JAXP中的DOM解析器步骤1.调用DocumentBuilderFactory.newInstance()方法得到创建DOM解析器的工厂 2.3.JAXP之DOM解析实例:XML文档如下: <?xml version="1.0" encoding="utf-8"?>
<班级>
<学生 地址="香港">
<名字>周小星</名字>
<年龄>23</年龄>
<介绍>学习刻苦</介绍>
</学生>
<学生 地址="澳门">
<名字>林晓</名字>
<年龄>25</年龄>
<介绍>是一个好学生</介绍>
</学生>
</班级>
2.3.1.读取XML文档首先使用2.2中介绍了三个步骤得到代表整个文档的document对象,并调用我们所写的 // 1.创建一个DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 2.通过工厂实例得到DocumentBuilder对象
DocumentBuilder builder = factory.newDocumentBuilder();
// 3.指定要解析的xml文件,返回document对象
Document document = builder.parse(new File("src/myClass.xml"));
read(document);
其中的read方法是这么写的: /** * 显示所有学生的所有信息 * @param document */
public static void read(Document document){
// 通过学生这个标签名字得到NodeList
NodeList nodeList = document.getElementsByTagName("学生");
for(int i=0;i<nodeList.getLength();i++){
// 因为Element是Node的子接口,所有这里可以转换成Element
// 从而可以使用更多的方法
Element student = (Element)nodeList.item(i);
// 获取属性
String address = student.getAttribute("地址");
System.out.println(address);
// 得到学生的所有子节点,并循环输出
NodeList childList = student.getChildNodes();
for(int j=0;j<childList.getLength();j++){
Node node = childList.item(j);
if(node.getNodeType() == Node.ELEMENT_NODE)
System.out.println(node.getNodeName()+":"+node.getTextContent());
}
System.out.println("-------------");
}
// 这样一层一层向下查询也可以
//Element name = (Element)student.getElementsByTagName("名字").item(0);
//System.out.println(name.getTextContent());
}
最后的运行结果如下所示: 2.3.2.更新XML文档利用DOM更新XML文档一定要使用Transformer类将更改写入文件,否则只是更改了在内存中的XML文档对象。
【1】添加元素 /** * 添加学生 * * @param document * @throws Exception */
public static void add(Document document) throws Exception {
// 创建一个新的学生节点
Element newStudent = document.createElement("学生");
// 给新的学生添加地址属性
newStudent.setAttribute("地址","旧金山");
// 创建学生的子节点
Element newStudent_name = document.createElement("名字");
newStudent_name.setTextContent("小明");
Element newStudent_age = document.createElement("年龄");
newStudent_age.setTextContent("25");
Element newStudent_intro = document.createElement("介绍");
newStudent_intro.setTextContent("这是一个好孩子");
// 将子节点添加到学生节点上
newStudent.appendChild(newStudent_name);
newStudent.appendChild(newStudent_age);
newStudent.appendChild(newStudent_intro);
// 把新的学生节点添加到根节点下
document.getDocumentElement().appendChild(newStudent);
// 更新XML文档
// 得到TransformerFactory
TransformerFactory tff = TransformerFactory.newInstance();
// 通过TransformerFactory得到一个转换器
Transformer tf = tff.newTransformer();
// 更新当前的XML文件
tf.transform(new DOMSource(document),new StreamResult(new File(
"src/myClass.xml")));
}
【2】删除元素 /** * 删除第一个学生节点 * * @param document */
public static void delete(Document document) throws Exception {
// 首先找到这个学生,这里可以不用转为Element
Node student = document.getElementsByTagName("学生").item(0);
// 通过它的父节点来删除
student.getParentNode().removeChild(student);
// 更新这个文档
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.transform(new DOMSource(document),new StreamResult(new File(
"src/myClass.xml")));
}
【3】更改元素的值 /** * 把第一个学生的元素名字改为宋江 * * @param document */
public static void update_name(Document document) throws Exception{
Element student = (Element) document.getElementsByTagName("学生").item(0);
Element name = (Element) student.getElementsByTagName("名字").item(0);
name.setTextContent("宋江");
// 更新这个文档
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.transform(new DOMSource(document),new StreamResult(new File(
"src/myClass.xml")));
}
【4】更改或删除元素的属性 /** * 删除第一个学生节点的属性 * * @param document */
public static void delete_attribute(Document document) throws Exception {
// 首先找到这个学生
Element student = (Element) document.getElementsByTagName("学生").item(0);
// 删除student的地址属性
student.removeAttribute("地址");
// 更新属性
// student.setAttribute("地址","新地址");
// 更新这个文档
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.transform(new DOMSource(document),new StreamResult(new File(
"src/myClass.xml")));
}
上述列举了几个更新元素(节点)的例子,更一般的需求是这样的:将名字是周小星的同学的年龄改为30,这时候我们需要去遍历XML文档,找到对应的节点,再进行修改。 另外,所有关于更新的方法中都用到了TransformerFactory来进行实际的更新,所以,我们可以把这三句话写成一个函数,从而避免代码冗余,如下: public static void update(Document document,String path) throws Exception {
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.transform(new DOMSource(document),new StreamResult(new File(path)));
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |