Dom4j
这里使用的目前最新的 dom4j-2.1.3 版本链接。
对应的 maven :
<!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>
注意,dom4j 的 2.1.x 版本对 jdk 的要求是 Java 8+。
Dom4j会将 XML 看成一个 Document 对象,将 XML 标签看成 Element 对象。
假设我们有一个 XML 文件:students.xml ,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<students>
<student no="001">
<name>张三</name>
<age>18</age>
<score>96</score>
<parents>
<father>阿强</father>
<mother>阿珍</mother>
</parents>
</student>
<student no="002">
<name>李四</name>
<age>19</age>
<score>99</score>
<parents>
<father>阿贵</father>
<mother>阿莲</mother>
</parents>
</student>
</students>
读取
首先,我们需要实例化 SAXReader 类,它是读取 XML 文件的核心类。调用其 read 方法读取 xml 文件,会生成一个 Document 对象。
String file = "/path/to/xml/test.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(file);
read 方法会抛出一个 DocumentException 异常。
我们可以使用 Document 对象中的 getRootElement 方法获取根节点,即此处的 <students> 标签:
Element root = document.getRootElement();
注意,所有的 XML 标签都对应着一个 Element 对象,即使是文档的根节点。
在 students.xml 文件中,<students> 根节点有两个 <student> 节点,我们可以使用 Element 对象的 elements 方法获取一组相同标签的集合:
List<Element> students = root.elements("student");
返回的集合中的每个元素仍然是 Element 类型的对象。
接下来,使用 for 循环遍历这个集合。
for (Element student : students) {
// element 方法用于获取唯一的子节点对象
Element nameElement = student.element("name");
// getText 方法用于获取标签文本
String name = nameElement.getText();
System.out.println("name: " + name);
}
对于一个 Element 对象,如果想要获取其子元素,则调用其 element 方法,如:
Element nameElement = student.element("name");
Element 对象还有一个 getText 方法用于获取标签文本,
String name = nameElement.getText();
当然,你也可以直接获取子元素的文本,只需要调用 Element 对象的 elementText 方法:
// elementText 方法用于获取指定标签的文本
String age = student.elementText("age");
System.out.println("age: " + age);
对于一个元素的属性来说,可以使用 attribute 方法获取,该方法返回一个 Attribute 对象,调用 getText 方法可以获取属性的值:
Attribute noAttr = student.attribute("no");
String no = noAttr.getText();
System.out.println("no: " + no);
完整的代码示例如下:
public class Main {
public static void readXML() throws DocumentException {
String file = "/path/to/xml/test.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(file);
// 获取 XML 文档的根节点,即 <students> 标签
Element root = document.getRootElement();
// elements 方法用于获取指定的标签集合
List<Element> students = root.elements("student");
for (Element student : students) {
// attribute 方法用于获取标签属性
Attribute noAttr = student.attribute("no");
String no = noAttr.getText();
System.out.println("no: " + no);
// element 方法用于获取唯一的子节点对象
Element nameElement = student.element("name");
// getText 方法用于获取标签文本
String name = nameElement.getText();
System.out.println("name: " + name);
// elementText 方法用于获取指定标签的文本
String age = student.elementText("age");
System.out.println("age: " + age);
String score = student.elementText("score");
System.out.println("score: " + score);
Element parents = student.element("parents");
String father = parents.elementText("father");
String mother = parents.elementText("mother");
System.out.println("father: " + father);
System.out.println("mother: " + mother);
System.out.println("---------");
}
}
public static void main(String[] args) {
try {
readXML();
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
输出:
no: 001
name: 张三
age: 18
score: 96
father: 阿强
mother: 阿珍
---------
no: 002
name: 李四
age: 19
score: 99
father: 阿贵
mother: 阿莲
---------
写入
除了读取,我们还需要在 XML 文档中新增一些节点,以及将新生成的 XML 写入文件中。
新增节点,使用 Element 对象的 addElement 方法,该方法返回一个新生成的 Element 对象。我们可以对新生成的 Element 设置文本内容,或者再创建新的子节点:
Element root = document.getRootElement();
Element student = root.addElement("student");
student.addElement("name").setText("王五");
之后,当我们需要保存至文件的时候,只需要调用 Document 对象的 write 方法,传入相应的 Writer 输出流对象即可:
FileOutputStream fos = new FileOutputStream("/path/to/xml/test2.xml");
Writer writer = new OutputStreamWriter(fos);
document.write(writer);
writer.close();
fos.close();
当出现乱码时,可以尝试指定编码:
Writer writer = new OutputStreamWriter(fos, "UTF-8");
完整的代码示例如下:
public static void writeXML() throws DocumentException, IOException {
String file = "/path/to/xml/test.xml";
// SAXReader 是读取 XML 文件的核心类,用于将 XML 解析后以树的形式保存在内存中
SAXReader reader = new SAXReader();
Document document = reader.read(file);
Element root = document.getRootElement();
Element student = root.addElement("student");
student.addAttribute("no", "003");
student.addElement("name").setText("王五");
student.addElement("age").setText("20");
student.addElement("score").setText("100");
Element parents = student.addElement("parents");
parents.addElement("father").setText("阿发");
parents.addElement("mother").setText("阿梅");
FileOutputStream fos = new FileOutputStream("/path/to/xml/test2.xml");
Writer writer = new OutputStreamWriter(fos);
document.write(writer);
writer.close();
fos.close();
}