最近写个程序,其中要解析XML格式的文件,XML的好处都很清楚,
(1)便于不同应用程序之间通信。
(2)便于不同平台之间通信。
(3)便于不同平台之间数据共享。
通过Java解析XML,通常有四种方式,DOM、SAX、DOM4J和JDOM。
DOM的优点,
形成了树结构,直观,容易理解,代码更容易编写。
解析过程中树结构保存在内存中,方便修改。
缺点,
当xml文件较大时,对内存的耗费比较大,容易影响解析的性能,造成内存溢出。
SAX的优点,
采用事件驱动的模式,对内存的耗费比较小。
适用于只需要处理XML中数据时。
缺点,
不易编码。
很难同时访问同一个XML中的多处不同数据。
JDOM,
仅使用具体累而不使用接口。
API大量使用了Collections类。
DOM4J,
是JDOM的一种智能分支,合并了很多超出基本XML文档表示的功能。
DOM4J使用接口和抽象基本类方法,是一个优秀的Java XML API。
具有性能优异、灵活性好、功能强大和极端易用实用的特点。
开放源代码。
根据实际需求,选择了JDOM作为解析工具。
首先,引入jdom的三方包,
代码语言:javascript复制<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1</version>
</dependency>
测试的XML文件,如下所示,
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<studentInfo>
<student id="1">
<name>小明</name>
<age>28</age>
<birthday>19920114</birthday>
<home>河南</home>
</student>
<student id="2">
<name>小刚</name>
<age>29</age>
<birthday>19911114</birthday>
<home>湖北</home>
</student>
<student id="3">
<name>小红</name>
<age>28</age>
<birthday>19920115</birthday>
<home>湖南</home>
</student>
</studentInfo>
测试的代码,如下所示,
代码语言:javascript复制import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
publicclass ReadXmlJdomService {
public static void main(String[] args){
System.out.println("readXmlByJdom start:");
readXmlByJdom();
System.out.println("readXmlByJdom end.");
}
//jdom方式
private static void readXmlByJdom(){
List<Student> bList = new ArrayList<Student>();
try {
// 创建一个SAXBuilder对象
SAXBuilder builder = new SAXBuilder();
// 创建一个输入流
InputStream in = new FileInputStream("/test/test.xml");
// 处理乱码情况
InputStreamReader isr = new InputStreamReader(in, "UTF-8");
// 通过build方法,将输入流加载到SAXBuilder中
Document doc = builder.build(isr);
// 通过Document对象获取根节点
Element foo= doc.getRootElement();
// 获取根节点下子节点名
List<Element> allChildren = foo.getChildren();
// 进行解析
for (Element student : allChildren) {
Student b = new Student();
System.out.println("开始解析第" (allChildren.indexOf(student) 1) "个同学");
// 解析student属性集合
List<Attribute> attrList = student.getAttributes();
// 遍历(针对不清楚节点下属性名)
for (Attribute attr : attrList) {
System.out.println("属性名:" attr.getName() " -- 属性值:" attr.getValue());
if("id".equals(attr.getName())){
b.setId(attr.getValue());
}
}
// 清楚知道属性名获取属性值
String v = student.getAttributeValue("id");
System.out.println("清楚知道属性名" v);
// 对student节点子节点的节点名和节点值进行遍历
List<Element> studentChiles = student.getChildren();
for (Element element : studentChiles) {
System.out.println("属性名:" element.getName() " -- 属性值:" element.getValue());
if("name".equals(element.getName())){
b.setName(element.getValue());
}elseif("age".equals(element.getName())){
b.setAge(element.getValue());
}elseif("home".equals(element.getName())){
b.setHome(element.getValue());
}elseif("birthday".equals(element.getName())){
b.setBirthday(element.getValue());
}elseif("id".equals(element.getName())){
b.setId(element.getValue());
}
}
System.out.println("结束解析第" (allChildren.indexOf(student) 1) "个同学");
bList.add(b);
b = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
打印的解析过程,如下所示,
代码语言:javascript复制readXmlByJdom start:
开始解析第1个同学
属性名:id -- 属性值:1
清楚知道属性名1
属性名:name -- 属性值:小明
属性名:age -- 属性值:28
属性名:birthday -- 属性值:19920114
属性名:home -- 属性值:河南
结束解析第1个同学
开始解析第2个同学
属性名:id -- 属性值:2
清楚知道属性名2
属性名:name -- 属性值:小刚
属性名:age -- 属性值:29
属性名:birthday -- 属性值:19911114
属性名:home -- 属性值:湖北
结束解析第2个同学
开始解析第3个同学
属性名:id -- 属性值:3
清楚知道属性名3
属性名:name -- 属性值:小红
属性名:age -- 属性值:28
属性名:birthday -- 属性值:19920115
属性名:home -- 属性值:湖南
结束解析第3个同学
readXmlByJdom end.
通过这段代码,重点是需要理解他的解析过程,就可以根据实际用到的XML格式,写出对应的解析逻辑。
盯着这些代码,不一定能做大举一反三,动起来才能做到更深入地理解,因此,不能光纸上谈兵,实践很重要。