XML的四种解析器(dom,sax,jdom,dom4j)原理及性能比较
XML解析
对xml文件内部的配置解析之后可以用于框架的一些功能实现。
XML的解析在Java中分为四种方式:
1.DOM(Document Object Model)解析
将整个XML文档在内存中一次性加载,成为一颗倒置的文档数,可以通过解析器
在文档中任意的遍历;因此DOM解析适合解析少量xml文件,在大文件(XML)解析需要消耗大量内存,从而降低解析效率
2.SAX(Simple Api For XML)解析
采用的类似流媒体的加载方式,即读取一部分元素,解析一部分,解析完毕之后会释放内存,因此SAX 解析不需要消耗太多内存,从而提高解析的效率,但是不能像DOM解析一样在文档的任意节点读取
(除非缓存变量中)
3.JDOM解析
内部是基于SAX的API,通过Java实现XML解析,使用的是一些具体类实现解析
4.DOM4J(Document Object For Java)解析(基于JDOM优化分支)
DOM4J是基于JDOM的分支,在JDOM的基础上大量使用Java的集合API实现解析,并且DOM4J还支持快速节点检索方式(XPath)
下面是最常用DOM4J的具体XML代码:
test.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
DTD:文档类型定义,用于规范SCML文档中(包含HTML、XML等)的元素编写顺序以及内容组织方式
XSD:专用于XML文档的定义文件
-->
<!DOCTYPE users [
<!ELEMENT users (user+)>
<!ELEMENT user ANY>
<!-- ANY表示任意位置-->
<!-- <!ELEMENT user (name,age,sex)> 表示按name,age,sex的顺序-->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST user id CDATA #REQUIRED>
]>
<!--
xml的声明规范:
1.xml文档中有且仅有一对根标签
2.标签必须成对出现,单标签必须内部结束
3.标签名称必须保持大小写一致
4.属性值必须双引号包含
5.属性声明在开始标签中
-->
<users>
<!-- user#100$*3>name{softeem$}+age{2$}+sex{男}-->
<user id="1001">
<name>softeem1</name>
<age>21</age>
<sex>男</sex>
</user>
<user id="1002">
<name>softeem2</name>
<age>22</age>
<sex>男</sex>
</user>
<user id="1003">
<name>softeem3</name>
<age>23</age>
<sex>男</sex>
</user>
</users>
Java解析代码:
public List<User> parse(String xmlFileName) throws DocumentException {
List<User> users = new ArrayList<>();
//创建DOM4J解析器对象
SAXReader reader = new SAXReader();
//获取指定文件的输入流
InputStream is = this.getClass().getResourceAsStream("/" + xmlFileName);
//加载流成为一个文档对象
Document doc = reader.read(is);
//获取文档的根元素
Element root = doc.getRootElement();
//获取根元素下的所有user元素
List list = root.elements("user");
for (Object o:list){
Element e = (Element)o;
//只要循环执行一次得到一个用户对象
User user = new User();
//获取元素中得id属性值
String id = e.attributeValue("id");
//获取当前元素下的子元素的文本值
String name = e.element("name").getTextTrim();
String age = e.element("age").getTextTrim();
String sex = e.elementTextTrim("sex");
//将获取属性值存到user对象中
user.setUid(Integer.parseInt(id));
user.setName(name);
user.setAge(Integer.parseInt(age));
user.setSex(sex);
//将对象存在集合中
users.add(user);
}
return users;
}
XMl对应的User类
public class User {
private int uid;
private String name;
private String sex;
private int age;
public User() {
}
public User(int uid, String name, String sex, int age) {
this.uid = uid;
this.name = name;
this.sex = sex;
this.age = age;
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}