主要介绍解析XML的两种方式
DOM4J解析:
面向对象,由于是一次性读取整个文档到内存中,读取大文件的时候可能会造成内存占用过多。
SAX解析:基于事件,一次读取一部分,操作上比DOM4J繁琐一点,不会造成内存占用问题。
DOM 解析 | SAX 解析 | |
---|---|---|
原理 | 一次性加载,内存占用比较大 | 加载一点,读取一点,内存占用小 |
读取顺序 | 可以任意读取,可以往回读 | 只能从上往下依次读取,不能往回读 |
操作方式 | 可查询,也可修改 | 只能查询 |
编码方式 | 面向对象 | 基于事件 |
大纲
-
DOM4J 解析
- 导包
- 核心类和方法
- 读取XML
- 写出XML
- XPath
-
SAX 解析
jdk集成
- 核心类
- 读取XML文件加载对象到容器
DEMO
#DOM4J 解析
dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的工具。
##导包 下载JAR包
- dom4j-1.6.1.jar
##核心类和方法
SAXReader:负责XML文件的加载
XMLWriter:负责XML文件的输出
DocumentHelper:用来生成生成 XML 文档的工厂类
Element:元素节点
三个重要概念:标签、属性、文本
-
标签
Element
Method | Method Description |
---|---|
getRootElement() | 得到文档根元素 |
addElement("name") | 添加子标签 |
element("name") | 寻找指定标签名的子元素 |
elements("names") | 寻找指定标签名的子元素(全部) |
elements() | 寻找全部子元素 |
-
属性
Atrribute
Method | Method Description |
---|---|
atrributeValue("name") | 得到指定属性的值 |
addAtribute("name", "value") | 添加属性(以存在则修改) |
atrribute("name") | 得到属性对象 |
atrributes() | 全部属性对象列表 |
getName() | 得到属性名 |
getValue() | 得到属性值 |
- 文本
Method | Method Description |
---|---|
getText() | 得到文本信息 |
setText() | 修改文本信息 |
elementText("name") | 得到子标签的文本信息 |
- 其他
DocumentHelper.createDocument():创建新文档
detach():标签/属性自杀
getParent().remove(标签/属性):调用父类的删除方法来删除标签/属性
##读取XML
/**
* loading XML File Resource
* @param path XML Resource File Path
* @return XML Document Object
*/
public static Document reader(String path) {
Document document = null;
try {
return new SAXReader().read(XMLTools.class.getClassLoader().getResourceAsStream(path));
} catch (DocumentException e) {
e.printStackTrace();
}
return document;
}
Document read(File file)
Document read(URL url)
Document read(String systemId)
Document read(InputStream in)
Document read(Reader reader)
##写出XML
/**
* Writer XML File Resource
* @param document XML Document Object
* @param path XML Resource File Path
* @return result
*/
public static boolean writer(Document document, String path) {
boolean flag = true;
try {
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(
new FileWriter(XMLTools.class.getClassLoader().getResource(path).getPath()),
format
);
writer.write(document);
writer.close();
} catch (Exception e) {
flag = false;
e.printStackTrace();
}
return flag;
}
##XPath XPath语法
- 导包:jaxen-1.1-beta-6.jar
// 搜索多个节点
List<Node> nodes = document.selectNodes(XPath表达式);
// 搜索单个节点
Node node = document.selectSingleNode(XPath表达式);
#SAX 解析 jdk集成
SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。
##核心类
SAXParser:负责解析XML
DefaultHandler:负责监听加载XML触发的事件
- DefaultHandler
自定义一个类继承DefaultHandler类
- startDocument():文档开始
- endDocument():文档结束
- startElement():元素开始
- endElement():元素结束
- characters():文本
当前元素的 text 加载完
##读取XML配置加载对象到容器
下面是一个读取XML文件,通过反射技术生成对象并存放到容器的Demo
LoadObjectHandler.java
/**
* 读取XML文件加载对象到容器
*/
public class LoadObjectHandler extends DefaultHandler {
public static final String BEAN_NODE = "bean";
public static final String BEAN_NAME = "name";
public static final String BEAN_CLASS = "class";
// Object Container
private Map<String, Object> container = new HashMap<>();
/**
* 元素开始
*
* @param uri
* @param localName
* @param qName 标签名
* @param attributes 属性列表
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName != null && qName.equals(BEAN_NODE)) {
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
String name = attributes.getValue(BEAN_NAME);
String clazz = attributes.getValue(BEAN_CLASS);
try {
Class<?> mClass = getClass().forName(clazz);
Object obj = mClass.newInstance();
container.put(name, obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
/**
* 从容器返回对象
*
* @param name Object key
* @return Object
*/
public Object getObject(String name) {
return container.get(name);
}
}
test.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean name="User" class="tools.xml.test1.User"/>
</beans>
App.java
String path = "../resource/test.xml";
// 从工厂得到解析器
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
// 创建自定义监听器对象
LoadObjectHandler handler = new LoadObjectHandler();
// 解析XML文件
parser.parse(new File(XMLTools.class.getResource(path).getPath()), handler);
System.out.println(handler.getObject("User"));