杰瑞科技汇

java dom4j 读取xml

dom4j 是一个功能强大、性能优异且易于使用的 Java XML 框架,它广泛应用于各种项目中,它的核心特点是:

java dom4j 读取xml-图1
(图片来源网络,侵删)
  • 支持 XPath: 可以非常方便地使用 XPath 表达式来查找节点。
  • 支持 SAX, DOM, and JAXP: 提供了多种解析方式。
  • 性能优异: 通常比标准的 JDK org.w3c.dom 更快。
  • 易于使用: API 设计非常直观。

第一步:添加 dom4j 依赖

在使用 dom4j 之前,你需要确保你的项目中已经添加了它的依赖,如果你使用 Maven,请在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version> <!-- 建议使用较新版本 -->
</dependency>

注意: dom4j 的运行依赖于另一个 XML 解析库,通常是 jaxen,Maven 在引入 dom4j 时通常会自动将其作为传递依赖(transitive dependency)一并下载,所以你通常不需要手动添加。


第二步:准备一个示例 XML 文件

为了演示,我们创建一个名为 students.xml 的文件,内容如下:

students.xml

java dom4j 读取xml-图2
(图片来源网络,侵删)
<?xml version="1.0" encoding="UTF-8"?>
<class name="计算机科学1班">
    <student id="001">
        <name>张三</name>
        <age>20</age>
        <gender>男</gender>
        <courses>
            <course name="Java编程"/>
            <course name="数据结构"/>
        </courses>
    </student>
    <student id="002">
        <name>李四</name>
        <age>21</age>
        <gender>女</gender>
        <courses>
            <course name="算法设计"/>
            <course name="计算机网络"/>
        </courses>
    </student>
</class>

第三步:核心 API 简介

在开始解析之前,我们先了解几个核心的 dom4j 类:

  • SAXReader: 这是 dom4j 的核心解析器类,用于将 XML 文件读取并解析成一个 Document 对象。
  • Document: 代表整个 XML 文档的顶层对象,类似于一个树结构的根。
  • Element: 代表 XML 中的一个元素(节点),是 DocumentBranch 的子接口,我们大部分操作都是基于 Element
  • Attribute: 代表元素的属性。
  • Node: 是所有节点(Element, Attribute, Document 等)的公共父接口,提供了一些通用的方法。
  • XPath: 用于在 XML 文档中查找信息的语言。dom4j 对 XPath 提供了非常好的支持。

第四步:代码实现(多种读取方式)

下面我们通过完整的 Java 代码来演示如何读取 students.xml 文件。

读取根元素及其子元素(基础遍历)

这是最基本的方式,我们从根元素开始,逐层遍历子元素。

import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
public class Dom4jBasicReader {
    public static void main(String[] args) {
        try {
            // 1. 创建 SAXReader 对象,这是 dom4j 的解析器
            SAXReader reader = new SAXReader();
            // 2. 读取 XML 文件,获取 Document 对象
            //    注意:文件路径要正确,这里假设 students.xml 在项目根目录下
            Document document = reader.read(new File("students.xml"));
            // 3. 获取根元素
            Element rootElement = document.getRootElement();
            System.out.println("根元素名称: " + rootElement.getName());
            System.out.println("根元素属性 (name): " + rootElement.attributeValue("name"));
            System.out.println("---------------------------------");
            // 4. 遍历根元素下的所有子元素(即所有的 <student> 标签)
            List<Element> studentList = rootElement.elements("student");
            for (Element student : studentList) {
                // 5. 获取元素的属性
                String id = student.attributeValue("id");
                System.out.println("学生ID: " + id);
                // 6. 获取元素下的子元素文本内容
                String name = student.elementText("name");
                String age = student.elementText("age");
                String gender = student.elementText("gender");
                System.out.println("  姓名: " + name);
                System.out.println("  年龄: " + age);
                System.out.println("  性别: " + gender);
                // 7. 遍历嵌套的子元素(如 <courses>)
                Element coursesElement = student.element("courses");
                if (coursesElement != null) {
                    List<Element> courseList = coursesElement.elements("course");
                    System.out.print("  选修课程: ");
                    for (Element course : courseList) {
                        // 获取元素的属性
                        System.out.print(course.attributeValue("name") + " ");
                    }
                    System.out.println();
                }
                System.out.println("---------------------------------");
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

java dom4j 读取xml-图3
(图片来源网络,侵删)
根元素名称: class
根元素属性 (name): 计算机科学1班
---------------------------------
学生ID: 001
  姓名: 张三
  年龄: 20
  性别: 男
  选修课程: Java编程 数据结构 
---------------------------------
学生ID: 002
  姓名: 李四
  年龄: 21
  性别: 女
  选修课程: 算法设计 计算机网络 
---------------------------------

使用 XPath 快速定位节点

当 XML 结构复杂时,逐层遍历非常繁琐。dom4j 强大的 XPath 支持可以让我们直接“跳”到目标节点。

import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Dom4jXPathReader {
    public static void main(String[] args) {
        try {
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("students.xml"));
            // XPath 示例
            // 1. 获取所有名为 'student' 的节点
            //    // 表示从任意位置开始
            List<Node> allStudents = document.selectNodes("//student");
            System.out.println("所有学生数量: " + allStudents.size());
            // 2. 获取第一个学生的姓名
            //    / 表示从根开始
            String firstName = document.selectSingleNode("/class/student[1]/name").getText();
            System.out.println("第一个学生姓名: " + firstName);
            // 3. 获取ID为 '002' 的学生的姓名
            //    @ 表示属性
            Node secondStudentNode = document.selectSingleNode("//student[@id='002']");
            if (secondStudentNode != null) {
                String secondName = secondStudentNode.selectSingleNode("name").getText();
                System.out.println("ID为002的学生姓名: " + secondName);
            }
            // 4. 获取所有学生的姓名
            List<Node> allNames = document.selectNodes("//student/name");
            System.out.println("\n所有学生姓名列表:");
            for (Node nameNode : allNames) {
                System.out.println(nameNode.getText());
            }
            // 5. 获取所有课程名称
            List<Node> allCourseNames = document.selectNodes("//course/@name");
            System.out.println("\n所有课程名称列表:");
            for (Node courseNameNode : allCourseNames) {
                // 对于属性节点,使用 getStringValue() 或 getText()
                System.out.println(courseNameNode.getStringValue());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

所有学生数量: 2
第一个学生姓名: 张三
ID为002的学生姓名: 李四
所有学生姓名列表:
张三
李四
所有课程名称列表:
Java编程
数据结构
算法设计
计算机网络

第五步:处理 XML 声明和编码

dom4j 在读取 XML 时,会自动处理 XML 声明(<?xml version="1.0" encoding="UTF-8"?>)中声明的编码,你只需要确保在读取文件时,你的 Java 代码环境(IDE、文件系统)的编码与 XML 文件声明的编码一致即可。

如果需要手动获取文档的编码信息,可以通过 Document 对象:

// 在读取完 document 后
String encoding = document.getXMLEncoding();
System.out.println("XML 文档编码: " + encoding); // 输出: UTF-8

总结与最佳实践

  1. 选择合适的方法:

    • XML 结构简单或需要遍历所有节点,使用 基础遍历
    • XML 结构复杂或只需要提取特定信息,XPath 是首选,它更简洁、更高效。
  2. 异常处理: SAXReader.read() 方法会抛出 DocumentException,务必进行 try-catch 处理,以应对文件不存在、格式错误等情况。

  3. 空指针检查: 使用 element("name") 方法时,如果指定的子元素不存在,它会返回 null,在调用 .getText() 或其他方法前,最好进行空值检查,避免 NullPointerExceptionelementText("name") 方法相对安全,如果元素不存在,它会返回 null 而不是抛出异常。

  4. 资源管理: SAXReader 本身不涉及需要手动关闭的流(它内部会处理),但如果你使用的是 InputStreamReader 来构建 Document,请确保在使用后关闭它们。

通过以上步骤和示例,你应该已经掌握了使用 dom4j 读取 XML 文件的基本方法。dom4j 是一个非常强大的工具,熟练掌握它将大大提高你处理 XML 数据的效率。

分享:
扫描分享到社交APP
上一篇
下一篇