1、xml解析概述
当将数据存储在XML后,我们就希望通过程序获得XML的内容。如果我们使用Java基础所学习的IO知识是可以完成的,不过你需要非常繁琐的操作才可以完成,且开发中会遇到不同问题(只读、读写)。人们为不同问题提供不同的解析方式,并提交对应的解析器,方便开发人员操作XML。
2、解析方式和解析器
开发中比较常见的解析方式有三种,如下:
- DOM:要求解析器把整个XML文档装载到内存,并解析成一个Document对象。
a)、优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
b)、缺点:XML文档过大,可能出现内存溢出显现。 - SAX:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。
a)、优点:处理速度快,可以处理大文件
b)、缺点:只能读,逐行后将释放资源。 - PULL:Android内置的XML解析方式,类似SAX。
解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包。
常见的解析开发包:
- JAXP:sun公司提供支持DOM和SAX开发包
- JDom:dom4j兄弟
- jsoup:一种处理HTML特定解析开发包
- dom4j:比较常用的解析开发包,hibernate底层采用。
3、DOM解析原理及结构模型
XML DOM 和 HTML DOM类似,XML DOM 将 整个XML文档加载到内存,生成一个DOM树,并获得一个Document对象,通过Document对象就可以对DOM进行操作。
DOM中的核心概念就是节点,在XML文档中的元素、属性、文本等,在DOM中都是节点!
4、API使用
如果需要使用dom4j,必须导入jar包。
dom4j 必须使用核心类SaxReader加载xml文档获得Document,通过Document对象获得文档的根元素,然后就可以操作了。
- SaxReader对象
a)、read(…) 加载执行xml文档 - Document对象
a)、getRootElement() 获得根元素 - Element对象
a)、elements(…) 获得指定名称的所有子元素。可以不指定名称(获取一级子元素,不获取孙子元素)
b)、element(…) 获得指定名称第一个子元素。可以不指定名称
c)、getName() 获得当前元素的元素名
d)、attributeValue(…) 获得指定属性名的属性值
e)、elementText(…) 获得指定名称子元素的文本值
f )、getText() 获得当前元素的文本内容(如果用根目录调用这个方法,输出的是几行空白)
以下是一些例子
@Test
public void demo03() throws Exception{
//#1 获得document
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File("src/cn/itcast/a_xml/web.xml"));
//#2 获得根元素
Element rootElement = document.getRootElement();
//打印version属性值
String version = rootElement.attributeValue("version");
System.out.println(version);
//#3 获得所有子元素。例如:<servlet>/<servlet-mapping>
List<Element> allChildElement = rootElement.elements();
//#4 遍历所有
for (Element childElement : allChildElement) {
// #5.1 打印元素名
String childEleName = childElement.getName();
System.out.println(childEleName);
// #5.2 处理<servlet> ,并获得子标签的内容。例如:<servlet-name> 等
if("servlet".equals(childEleName)){
// 方式1:获得元素对象,然后获得文本
Element servletNameElement = childElement.element("servlet-name");
String servletName = servletNameElement.getText();
System.out.println("\t" + servletName);
// 方式2:获得元素文本值
String servletClass = childElement.elementText("servlet-class");
System.out.println("\t" + servletClass);
}
// #5.3 处理<servlet-mapping> 省略...
}
}
dom4j技术进行查询操作.
使用步骤:
1.导入jar包
2.创建一个核心对象 SAXReader
new SAXReader();
3.将xml文档加载到内存中形成一棵树
Document doc=reader.read(文件)
4.获取根节点
Element root=doc.getRootElement();
5.通过根节点就可以获取其他节点(文本节点,属性节点,元素节点)
获取所有的子元素
List<Element> list=root.elements()
获取元素的指定属性内容
String value=root.attributeValue("属性名");
获取子标签标签体:遍历list 获取到每一个子元素
String text=ele.elementText("子标签名称")
//遍历集合
for (Element ele : list) {
//获取servlet-name的标签体
String text = ele.elementText("servlet-name");
//System.out.println(text);
//获取url-pattern标签体
//System.out.println(ele.elementText("url-pattern"));
}
-----------------------------------------------------------------------------------
xpath解析技术:(扩展)
依赖于dom4j
使用步骤:
1.导入jar包(dom4j和jaxen-1.1-beta-6.jar)
2.加载xml文件到内存中
3.使用api
selectNode("表达式");
selectSingleNode("表达式");
表达式的写法:
/ 从根节点选取
// 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
例如一个标签下有一个id属性且有值 id=2;
//元素名[@属性名='属性值']
//元素名[@id='2']
package com.itheima.dom4j;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import org.xml.sax.SAXException;
public class test {
@Test
public void f1() throws SAXException, DocumentException{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("D:\\X_work\\eclipse\\workspace_eclipse-jee-mars-2-win32-x86_64\\shuzk_a_xml&dom4j\\xml\\web.xml");
Element rootElement = document.getRootElement();
String name1 = rootElement.getName();
System.out.println(name1);
String attributeValue1 = rootElement.attributeValue("version");
System.out.println(attributeValue1);
String text1 = rootElement.getText();
// System.out.println(text1);
List<Element> allChildElement = rootElement.elements();
for (Element childElement : allChildElement) {
String childElementName = childElement.getName();
System.out.println(childElement.getName());
// System.out.println(childElement.getText());
if("servlet".equals(childElementName)){
System.out.println("-----------");
Element servlet_name = childElement.element("servlet-name");
System.out.println(servlet_name.getName()+servlet_name.getText());
System.out.println("-----------");
String e=childElement.elementText("servlet-class");
System.out.println(e);
}
}
}
}