一、Dom4j概述
概念:采用DOM方式来解析XML文件
二、 DOM解析原理及结构模型
XML DOM 和 HTML DOM一样,XML DOM 将整个XML文档加载到内存,生成一个DOM树,并获得一个Document对象,通过Document对象就可以对DOM进行操作。
2.1核心
由于DOM方式解析XML文档所有都是节点,所有节点又都被封装到Document对象中,所以解析的重点就是获取Document对象。
2.2 DOM树的组成元素
组成 | 解释 |
---|---|
Document | 文档对象:代表整个xml文档 |
Node | 节点 |
Element | 元素 |
Attribute | 属性 |
Text | 文本 |
三、获得Document对象
概述:一个XML文件加载到内存中时就会创建一个Document对象,该Document对象包含了XML中的所有节点内容,通过该对象就可以获得对应XML文件的所有内容。
1.xml文件准备
有如下xml文件:
这个students.xml文件必须放在src下
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="1" excellent="true">
<name>小红</name>
<sex>女</sex>
<phone>xiaomi7</phone>
</student>
<student id="2" excellent="false">
<name>李四</name>
<sex>男</sex>
<phone>iphonex</phone>
</student>
<student id="3" excellent="false">
<name>灰太狼</name>
<sex>男</sex>
<phone>xiaomi8</phone>
</student>
</students>
2.在得到文档对象之前必须导入dom4j-2.1.1.jar
步骤:
- 去官网下载 zip 包。http://www.dom4j.org/
- 在项目中创建一个文件夹:lib
- 将dom4j-2.1.1.jar文件复制到 lib 文件夹
- 在jar文件上点右键,选择 Add as Library -> 点击OK
- 在类中导包使用
效果如图所示:
3.得到Document文档对象
步骤:
文件students.xml放在src目录下
- 创建一个SAXReader对象,用于读取 xml 文件。
- 从类路径下加载xml文件,得到输入流对象
- 通过 SAXReader对象的read(InputStream in )方法,从输入流中读取,生成文档对象。
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;
/**
* 使用 dom4j 解析工具读取 xml 文件
*/
public class Demo1 {
/**
* 得到文档对象
*/
@Test
public void getDocument() throws DocumentException {
//创建SAXReader对象
SAXReader reader = new SAXReader();
//读取src目录下的文件,得到输入流
InputStream in = Demo1.class.getResourceAsStream("/students.xml");
//从输入流中得到文档对象
Document document = reader.read(in);
//打印document
System.out.println(document);
下面列举Element常用方法并用一个案例来使用其中大部分的方法
// 方法名 功能说明
// String getName() 得到标签的名字
// Element element(name) 获得指定名字的元素对象
// List<Element> elements() 获得当前元素下所有的子元素对象
// List<Element> elements(name) 获得当前元素下指定名字的所有子元素对象
Element中与属性相关方法
//方法名 功能说明
//Attribute attribute(name) 根据属性名获得一个属性对象
//String attributeValue(name) 根据属性名获得属性值,返回字符串
//List<Attribute> attributes() 获得当前元素的所有属性对象,返回List集合
Attribute常用方法
//方法名 功能说明
//String getName() 获得属性的名字
//String getValue() 获得属性的值
结论:得到属性值的两种方式
1. 先得到Attribute对象,再通过对象的方法得到属性名和属性值
2. 直接通过属性的名字得到字符串类型的属性值。
Text文本元素
概述:
得到文本元素的前提:先得到元素Element,再得到元素下的文本
注意事项:
空格、换行、制表符:也是属于文本的一部分,所以在解析xml文件的时候,格式化XML文件要注意。
得到文本信息的方法:
//Element元素中的方法 说明
//String getText() 得到当前元素内部的文本
//String elementText(元素名) 通过子元素名字得到子元素内部的文本
//String elementTextTrim(元素名) 通过子元素名字得到子元素内部的文本,并且去掉前后的空格
案例演示:
利用 Dom4j 的知识,将 students.xml 文件中的学生数据封装成集合,其中每个元素是实体类 Student。打印输出 List 中的每个元素
1.xml文件用上面准备好的students.xml文件
2.实体类
//学生实体类
public class Student {
private int id;
private String name;
private String sex;
private String phone;
//有参构造方法
public Student(int id, String name, String sex, String phone) {
this.id = id;
this.name = name;
this.sex = sex;
this.phone = phone;
}
//无参构造方法
public Student() {
}
// get set 方法
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
//重写toString
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex=" + sex +
", phone='" + phone + '\'' +
'}';
}
}
测试类
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.ArrayList;
import java.util.List;
public class Demo05 {
public static void main(String[] args) throws DocumentException {
List<Student> students = new ArrayList<>();//创建空集合存储学生对象
SAXReader reader = new SAXReader();
//获取文档对象
Document read = reader.read(Demo05.class.getResourceAsStream("/students.xml"));
Element rootElement = read.getRootElement();//获取根元素
List<Element> elements = rootElement.elements();//得到所有标签(得到根元素下所有子元素)
for (Element element : elements) {//遍历得到每个标签
Student student = new Student();//创建学生对象
int id = Integer.parseInt(element.attributeValue("id"));//获取标签中有id这个属性的值并且转换成int类型
student.setId(id);//给对象中的id赋值
String name = element.elementText("name");//获取标签中有name这个标签的文本值
student.setName(name);//给对象中name赋值
//获取所有标签中有sex这个标签的文本值
String sex = element.elementText("sex");
//给对象中sex赋值
student.setSex(sex);
//获取所有标签中有phone这个标签的文本内容
String phone = element.elementText("phone");
//给对象中phone赋值
student.setPhone(phone);
students.add(student);//把每次创建好并且赋值完毕的对象添加进list集合中
}
for (Student student : contacts) {//遍历list集合并且打印元素
System.out.println(student);
}
}
}
运行main方法后的测试效果如图所示: