Dom4J解析XML文件

本文最后更新于:March 13, 2023 am

Dom4J是一个Java的XML API,是Jdom的升级品,用来读写XML文件的。Dom4J是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,越来越多的Java软件都在使用Dom4J来读写XML。

目录

最近看了下MyBatis的源码,准备手写一个简易的MyBatis框架。但因为涉及到比较多的XML文件解析,所以在此记录一下如何使用Dom4J解析XML文件。所以,本文也主要以读取解析MyBatis的配置文件为例。

首先看一下需要读取的文件内容:

mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jwgl?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="loong461"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/XsxkbMapper.xml"/>
</mappers>
</configuration>

依赖

1
2
3
4
5
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>

使用Dom4J的步骤主要分为三步:

  • 创建解析器对象;
  • 使用解析器对象读取XML文档,并生成Document对象。
  • 通过Document对象获取XML标签信息。

常用API

首先我们先来看一些比较重要的API。

Document对象的主要API:

获取根标签元素Element对象:Element getRootElement();

1
2
3
4
5
6
7
8
9
10
public class ParseXML {
public static void main(String[] args) throws Exception {
String MyBatisMainConfigFilePath = "mybatis-config.xml";
String MyBatisMapperFilePath = "mappers/XsxkbMapper.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(ClassLoader.getSystemClassLoader().getResourceAsStream(MyBatisMainConfigFilePath));
Element rootElement = document.getRootElement();
System.out.println("MyBatis主配置文件的根标签名称为:" + rootElement.getName()); // MyBatis主配置文件的根标签名称为:configuration
}
}

Element对象的主要API:

获取Element元素的名称,标签名称:String getName();

获取指定Element对象下的所有子标签。

1
2
3
List<Element> elements(); // 获取指定Element对象下的所有子标签
List<Element> elements(String var1); // 获取指定Element对象下所有的指定名称的子标签
Element element(String var1); // 获取指定Element对象下的第一个子标签

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ParseXML {
public static void main(String[] args) throws Exception {
String MyBatisMainConfigFilePath = "mybatis-config.xml";
String MyBatisMapperFilePath = "mappers/XsxkbMapper.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(ClassLoader.getSystemClassLoader().getResourceAsStream(MyBatisMainConfigFilePath));
Element rootElement = document.getRootElement();
System.out.println("MyBatis主配置文件的根标签名称为:" + rootElement.getName());
List<Element> elements = rootElement.elements();
List<Element> elements2 = rootElement.elements("environments");
Element environments = rootElement.element("environments");
System.out.printf("指定标签为:%s\n",environments.getName());
elements.forEach(it -> System.out.println("ele-1:"+it.getName()));
elements2.forEach(it -> System.out.println("ele-2:"+it.getName()));
}
}

// 输出
MyBatis主配置文件的根标签名称为:configuration
指定标签为:environments
ele-1:environments
ele-1:mappers
ele-2:environments

获取标签指定属性值

1
2
String attributeValue(String var1); // 获取指定var1属性的值,无则为null
String attributeValue(String var1, String defaultValue); // 获取指定var1属性的值,若无值则赋值为defaultValue

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class ParseXML {
public static void main(String[] args) throws Exception {
String MyBatisMainConfigFilePath = "mybatis-config.xml";
String MyBatisMapperFilePath = "mappers/XsxkbMapper.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(ClassLoader.getSystemClassLoader().getResourceAsStream(MyBatisMainConfigFilePath));
Element rootElement = document.getRootElement();
System.out.println("MyBatis主配置文件的根标签名称为:" + rootElement.getName());
List<Element> elements = rootElement.elements();
elements.forEach(it -> {
System.out.println(it.getName()+" 的default值为"+it.attributeValue("default","init"));
});
}
}

// 输出
MyBatis主配置文件的根标签名称为:configuration
environments 的default值为development
mappers 的default值为init

获取标签间的内容

1
2
3
String getText(); // 获取标签间的内容
String getTextTrim(); // 获取标签间的内容,同时去掉首尾的空白符
String elementText(String var1); // 获取当前Element对象下的指定的var1标签间的内容

结合XPath

Dom4J结合XPath使用路径表达式来选取XML文档中的元素或者属性节点。通过元素路径来完成对元素的查找。

XPath语法

大致可以理解成文件系统路径一下。

表达式 描述
node_name 选取此节点的所有子节点。
/ 绝对路径匹配,从根节点选取。只找一层。
// 相对路径匹配,从所有节点中查找当前选择的节点,包括子节点和后代节点,其第一个 / 表示根节点。会找所有的,全文搜索某节点。
. 选取当前节点。
.. 选取当前节点的父节点。
@ 选取属性值,通过属性值选取数据。常用元素属性有 @id 、@name、@type、@class、@tittle、@href。

依赖

使用需要先导依赖:

1
2
3
4
5
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>

常用API

1
2
Node selectSingleNode(String xpathExpression); // 根据xpath表达式获取第一个节点(标签)
List<Node> selectNodes(String xpathExpression); // 根据xpath表达式获取所有节点(标签)

示例

先在主配置文件中增加些配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/jwgl?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="test2">
<transactionManager type="MANAGED"/>
<dataSource type="UNPOOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mappers/XsxkbMapper1.xml"/>
<mapper resource="mappers/XsxkbMapper2.xml"/>
<mapper resource="mappers/XsxkbMapper3.xml"/>
<mapper resource="mappers/XsxkbMapper4.xml"/>
</mappers>
</configuration>

绝对查找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.tothefor.MybatisMember;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.util.List;

/**
* @Author DragonOne
* @Date 2023/3/12 22:54
* @墨水记忆 www.tothefor.com
*/
public class ParseXML {
public static void main(String[] args) throws Exception {
String MyBatisMainConfigFilePath = "mybatis-config.xml";
String MyBatisMapperFilePath = "mappers/XsxkbMapper.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(ClassLoader.getSystemClassLoader().getResourceAsStream(MyBatisMainConfigFilePath));
Element rootElement = document.getRootElement();
Element element = (Element) rootElement.selectSingleNode("/configuration/environments/environment");
System.out.println(element.getName() + " 的值为:" + element.attributeValue("id"));
List<Node> nodes = rootElement.selectNodes("/configuration/environments/environment");
System.out.println("====");
nodes.forEach(it -> {
Element temp = (Element) it;
System.out.println(temp.getName() + " 的值为:" + temp.attributeValue("id"));
});
}
}

// 输出
environment 的值为:development
====
environment 的值为:development
environment 的值为:test2

相对路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.tothefor.MybatisMember;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.util.List;

/**
* @Author DragonOne
* @Date 2023/3/12 22:54
* @墨水记忆 www.tothefor.com
*/
public class ParseXML {
public static void main(String[] args) throws Exception {
String MyBatisMainConfigFilePath = "mybatis-config.xml";
String MyBatisMapperFilePath = "mappers/XsxkbMapper.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(ClassLoader.getSystemClassLoader().getResourceAsStream(MyBatisMainConfigFilePath));
Element rootElement = document.getRootElement();
Element element = (Element) rootElement.selectSingleNode("/configuration/environments/environment/dataSource");
System.out.println(element.getName());
Element broEl = (Element) element.selectSingleNode("../transactionManager");
System.out.println(broEl.getName());
Element preEl = (Element) element.selectSingleNode(".."); // 父节点
System.out.println(preEl.getName());
}
}

// 输出
dataSource
transactionManager
environment

全文搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.tothefor.MybatisMember;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.util.List;

/**
* @Author DragonOne
* @Date 2023/3/12 22:54
* @墨水记忆 www.tothefor.com
*/
public class ParseXML {
public static void main(String[] args) throws Exception {
String MyBatisMainConfigFilePath = "mybatis-config.xml";
String MyBatisMapperFilePath = "mappers/XsxkbMapper.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(ClassLoader.getSystemClassLoader().getResourceAsStream(MyBatisMainConfigFilePath));
Element rootElement = document.getRootElement();
Element element = (Element) rootElement.selectSingleNode("//mapper");
System.out.println(element.getName() + " 的值为:" + element.attributeValue("resource"));
List<Node> nodes = rootElement.selectNodes("//mapper");
System.out.println("====");
nodes.forEach(it -> {
Element temp = (Element) it;
System.out.println(temp.getName() + " 的值为:" + temp.attributeValue("resource"));
});
}
}

// 输出
mapper 的值为:mappers/XsxkbMapper1.xml
====
mapper 的值为:mappers/XsxkbMapper1.xml
mapper 的值为:mappers/XsxkbMapper2.xml
mapper 的值为:mappers/XsxkbMapper3.xml
mapper 的值为:mappers/XsxkbMapper4.xml

条件查找

根据标签的某属性值进行查找:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.tothefor.MybatisMember;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.util.List;

/**
* @Author DragonOne
* @Date 2023/3/12 22:54
* @墨水记忆 www.tothefor.com
*/
public class ParseXML {
public static void main(String[] args) throws Exception {
String MyBatisMainConfigFilePath = "mybatis-config.xml";
String MyBatisMapperFilePath = "mappers/XsxkbMapper.xml";
SAXReader reader = new SAXReader();
Document document = reader.read(ClassLoader.getSystemClassLoader().getResourceAsStream(MyBatisMainConfigFilePath));
Element rootElement = document.getRootElement();
Element element = (Element) rootElement.selectSingleNode("//property[@name='url']"); // property标签中name属性值为url的
System.out.println(element.getName() + " 的值为:" + element.attributeValue("name"));
}
}


// 输出
property 的值为:url

本文作者: 墨水记忆
本文链接: https://tothefor.com/DragonOne/ee663feb.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!