如何使用DOM4J解析XML文件并写出完整示例代码?

来源:我的博客作者:陈远山头衔:网络博主
导读:本期聚焦于陈远山创作的《如何使用DOM4J解析XML文件并写出完整示例代码?》,敬请观看详情。把一段XML文档读进内存后该选哪种解析方式,常常让刚接触Java处理配置文件的同学纠结。DOM4J基于树模型把节点全部映射成可遍历的对象,比原生SAX更直观,又比JDK自带DOM轻量。本文直接给出可运行的读取、遍历与写入示例,说明Document、Element和Attribute之间的关系,并指出命名空间处理、大文件内存占用这两个容易踩坑的地方。掌握这几段代码,日常解析Spring配置文件或自定义报文都不用再查文档。

在Java生态中处理XML数据,DOM4J是一个非常流行且易用的开源库。它采用面向树的解析模型,将整个XML文档加载为内存中的Document对象,开发者可以通过简单的API像操作集合一样访问节点、属性以及文本内容。相比JDK自带的DOM接口,DOM4J的语法更加简洁;相比SAX这种基于事件的流式解析,它允许随机读写,更适合配置文件和中小型报文的处理场景。

如何使用DOM4J解析XML文件并写出完整示例代码?

DOM4J的基础依赖与Document对象构建

要在项目中使用DOM4J,首先需要将对应的jar包引入classpath。以Maven工程为例,通常在pom.xml里声明dom4j依赖即可。DOM4J底层依赖JAXP的解析器,但对外屏蔽了繁琐的工厂类调用,统一通过SAXReader来完成文档读取。理解Document对象是使用DOM4J的第一站,它代表整个XML树的根容器,所有Element和Attribute都是它的后代节点。

下面的代码展示了如何从文件系统加载一个XML并获取根元素。注意SAXReader的read方法可以接收File、InputStream或者URL,这在处理不同来源的配置时非常灵活。如果XML中包含声明编码,DOM4J会自动按照声明解码,不需要手动指定字符集,避免了常见的乱码问题。

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;

public class Dom4jBasic {
    public static void main(String[] args) {
        SAXReader reader = new SAXReader();
        try {
            // 从本地文件读取XML构建Document对象
            Document doc = reader.read(new File("C:\\config\\app.xml"));
            Element root = doc.getRootElement();
            System.out.println("根节点名称: " + root.getName());
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

上述示例中路径使用了Windows风格的反斜杠,在Java字符串中反斜杠本身需要转义写成双反斜杠,但在实际文件系统中它依然是C:\config\app.xml这样的路径结构。如果XML体积不大,这种一次性读入内存的方式代码量最少,也最容易调试。不过要留意,当文件超过几百兆时,Document会占用大量堆空间,此时应考虑换用基于事件的解析方案。

遍历元素与读取属性的实用写法

拿到根元素之后,真正的业务往往是要提取特定子节点的值或者遍历同构的列表。DOM4J提供了element(String name)获取单个子节点,以及elements()返回List<Element>的方式。对于属性,Element对象自带attributeValue(String name)方法,可以直接拿到字符串结果,不必像原生DOM那样先取Node再转型。

假设我们有一份用户列表的XML,每个user节点带id属性并包含name和age子元素。下面的示例演示了如何安全地遍历并打印内容。这里使用了elementTextTrim方法来读取子元素文本,它会自动去掉首尾空白,比先getElement再getText再trim要省事很多。

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;

public class Dom4jTraverse {
    public static void main(String[] args) throws Exception {
        SAXReader reader = new SAXReader();
        Document doc = reader.read("C:\\data\\users.xml");
        Element root = doc.getRootElement();
        List<Element> userList = root.elements("user");
        for (Element user : userList) {
            String id = user.attributeValue("id");
            String name = user.elementTextTrim("name");
            String age = user.elementTextTrim("age");
            System.out.println("id=" + id + ", name=" + name + ", age=" + age);
        }
    }
}

在实际项目中,XML结构可能嵌套较深,如果每一层都用硬编码名称去取,代码会变得脆弱。一种改进思路是写一个通用的递归方法,根据节点类型做不同处理;另一种是使用DOM4J支持的XPath表达式,直接用路径字符串定位节点。XPath适合结构复杂但查询模式固定的场景,它能把多层循环压缩成一行selectNodes调用,显著提升可读性。

需要提醒的是,当XML带有命名空间时,直接用element("book")可能返回null,因为真实名称变成了带前缀的限定名。此时要在SAXReader上调用setFeature关闭命名空间感知,或者在XPath里注册命名空间映射。很多初学者在这个坑上耗费过时间,其实只要在读取前明确业务是否真的需要区分命名空间就能提前规避。

使用DOM4J生成并写出新的XML文档

解析只是单向操作,更多时候我们还需要把内存中的对象树写回文件,比如导出报表或生成请求报文。DOM4J通过DocumentHelper创建空Document,再利用addElement链式构建节点。写文件则依赖XMLWriter配合OutputFormat,可以指定缩进和编码,让生成的文件既机器可读也方便人眼检查。

以下代码从零创建一份包含书籍信息的XML,并输出到磁盘。OutputFormat.createPrettyPrint会让节点自动换行缩进,而setEncoding确保中文不会写成乱码实体。相比手动拼接字符串,这种方式不容易漏掉闭合标签,也方便后续再读取回来。

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import java.io.FileOutputStream;

public class Dom4jWrite {
    public static void main(String[] args) throws Exception {
        Document doc = DocumentHelper.createDocument();
        Element root = doc.addElement("library");
        Element book = root.addElement("book");
        book.addAttribute("id", "1");
        book.addElement("title").setText("编程思想");
        book.addElement("author").setText("Bruce");
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("C:\\out\\lib.xml"), format);
        writer.write(doc);
        writer.close();
    }
}

在写出大批量数据时,建议复用同一个XMLWriter并分批flush,而不是累积完所有节点再一次性写盘,这样能把内存峰值降下来。另外如果目标系统对XML声明行有严格要求,可以通过format.setSuppressDeclaration控制是否输出<?xml version="1.0"?>。DOM4J默认会带声明,这在多数Web接口里没问题,但某些老旧交换协议可能要求纯节点内容。

综合来看,DOM4J在易用性和功能性之间取得了不错的平衡。掌握读取、遍历和写出这三组核心API,就能应付绝大多数Java项目里的XML处理任务。若后续遇到性能瓶颈,再结合XPath或切换解析模式也不迟,基础代码无需推倒重来。

DOM4JXML解析Java修改时间:2026-08-24 04:38:37

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。