Java解析XML字符串:DOM与DOM4J两种实现方式

6 次阅读

XML作为一种通用的数据交换格式,在Java开发中经常用于配置文件、接口通信、数据存储以及系统集成等场景。面对XML字符串解析需求时,开发者通常会选择Java原生提供的DOM方式,或者使用更加灵活便捷的第三方框架DOM4J。两种方式都可以完成XML读取、节点查询、属性获取等操作,但在使用体验、性能表现和适用场景方面存在明显差异。

Java解析XML字符串的常见应用场景

XML数据通常具有树形结构,由文档、元素、属性、文本节点等部分组成。例如:

XML

    1001
    Tom
    25

Java程序解析XML字符串后,可以获取用户编号、姓名、年龄等信息,并转换成Java对象,方便后续业务处理。

常见应用场景包括:

  • 读取系统配置文件;

  • 解析第三方接口返回数据;

  • 处理SOAP Web Service消息;

  • 实现不同系统之间的数据交换;

  • 读取复杂层级业务数据。

Java解析XML主要有以下几种技术:

  • DOM(Document Object Model)

  • SAX(Simple API for XML)

  • StAX(Streaming API for XML)

  • DOM4J

其中DOM和DOM4J由于使用方式直观、功能完善,被大量项目采用。

使用Java原生DOM解析XML字符串

DOM是Java标准库提供的XML解析方式,通过将整个XML文档加载到内存中,形成一棵完整的文档树,然后通过节点操作访问数据。

Java中主要使用:

  • DocumentBuilderFactory

  • DocumentBuilder

  • Document

  • Node

  • Element

等API完成解析。

DOM解析XML示例

假设需要解析以下XML字符串:

Java
String xml = 
        "" +
        "1001" +
        "Tom" +
        "25" +
        "";

完整解析代码如下:

Java
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;

public class DomXmlParser {

    public static void main(String[] args) throws Exception {

        String xml = 
                "" +
                "1001" +
                "Tom" +
                "25" +
                "";

        DocumentBuilderFactory factory =
                DocumentBuilderFactory.newInstance();

        DocumentBuilder builder =
                factory.newDocumentBuilder();

        Document document =
                builder.parse(
                    new ByteArrayInputStream(
                        xml.getBytes(StandardCharsets.UTF_8)
                    )
                );

        Element root = document.getDocumentElement();

        NodeList names = root.getElementsByTagName("name");

        System.out.println(
                "姓名:" + names.item(0).getTextContent()
        );
    }
}

运行结果:

姓名:Tom

DOM解析流程分析

DOM解析主要步骤如下:

  1. 创建DocumentBuilderFactory对象;

  2. 创建DocumentBuilder解析器;

  3. 将XML字符串转换为输入流;

  4. 调用parse方法生成Document对象;

  5. 通过节点对象获取XML内容。

Document对象代表整个XML文档,可以通过它获取根节点:

Java
Element root = document.getDocumentElement();

然后继续访问子节点:

Java
root.getElementsByTagName("节点名称");

这种方式结构清晰,适合处理层级较少、数据量较小的XML文件。

DOM解析方式的优点与不足

DOM的优点

  1. Java原生支持

无需引入额外依赖,适合简单项目或基础功能开发。

  1. 操作方式直观

XML被转换成树结构后,可以自由访问任意节点。

  1. 支持修改XML

DOM不仅可以读取数据,还可以创建、删除、修改节点。

例如:

Java
Element element = document.createElement("email");
element.setTextContent("test@example.com");
root.appendChild(element);

DOM的不足

  1. 内存占用较高

DOM会一次性加载整个XML文档,如果XML文件较大,容易造成内存压力。

  1. API使用复杂

节点类型较多,开发过程中需要处理Document、Node、Element等对象。

  1. 代码量较多

相比第三方框架,DOM完成同样功能需要编写更多代码。

使用DOM4J解析XML字符串

DOM4J是Java生态中非常流行的XML解析框架,它提供了更加友好的API,可以快速完成XML读取、修改和生成。

使用DOM4J前,需要添加依赖。

Maven配置:

XML

    org.dom4j
    dom4j
    2.1.4

DOM4J解析XML示例

使用同样的XML数据:

Java
String xml =
        "" +
        "1001" +
        "Tom" +
        "25" +
        "";

解析代码:

Java
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public class Dom4jXmlParser {

    public static void main(String[] args) throws Exception {

        String xml =
                "" +
                "1001" +
                "Tom" +
                "25" +
                "";

        Document document =
                DocumentHelper.parseText(xml);

        Element root =
                document.getRootElement();

        Element name =
                root.element("name");

        System.out.println(
                "姓名:" + name.getText()
        );
    }
}

输出:

姓名:Tom

DOM4J解析XML的代码明显更加简洁。

DOM4J节点遍历方式

如果XML存在多个相同节点,例如:

XML

    
        Tom
    
    
        Jerry
    

可以通过elements方法遍历:

Java
List<Element> users = root.elements("user");

for(Element user : users){

    String name =
            user.elementText("name");

    System.out.println(name);
}

输出:

Tom
Jerry

DOM4J通过Element对象直接操作节点,避免了大量Node类型转换。

DOM与DOM4J的区别对比

对比项目DOMDOM4J
类型Java标准API第三方XML框架
使用难度较高简单
性能中等较好
内存占用较高较高
XPath支持需要额外处理原生支持较好
修改XML支持支持
项目使用率基础场景较多企业项目常用

从开发效率来看,DOM4J具有明显优势;如果项目要求零依赖或者使用Java标准能力,则DOM更加合适。

DOM4J结合XPath查询XML

DOM4J支持XPath表达式,可以快速定位复杂节点。

例如:

XML

    
        Jack
    

查询员工姓名:

Java
Node node =
    document.selectSingleNode("//employee/name");

System.out.println(node.getText());

XPath可以避免多层循环查找,提高代码可读性。

常见XPath写法:

获取所有节点:

Java
//user

获取指定属性:

Java
//user[@id='100']

获取指定子节点:

Java
//user/name

XML解析中的安全问题

解析XML字符串时,需要注意XML外部实体攻击(XXE)。

攻击者可能利用DTD功能读取服务器文件或发起网络请求,因此生产环境中应关闭外部实体解析。

DOM安全配置示例:

Java
DocumentBuilderFactory factory =
        DocumentBuilderFactory.newInstance();

factory.setFeature(
    "http://apache.org/xml/features/disallow-doctype-decl",
    true
);

对于接口数据解析、文件上传解析等场景,安全配置非常重要。

如何选择DOM和DOM4J

不同业务场景可以采用不同方案:

适合使用DOM的情况

  • XML数据量较小;

  • 不希望增加第三方依赖;

  • 需要直接操作XML节点;

  • 学习XML底层解析机制。

适合使用DOM4J的情况

  • 企业Java项目;

  • 需要快速开发;

  • XML结构复杂;

  • 需要XPath查询;

  • 频繁读取和转换XML数据。

实际开发中,很多传统Java项目、Spring项目以及企业级系统都会选择DOM4J,因为它能够降低XML处理代码复杂度。

总结

Java解析XML字符串主要可以采用DOM和DOM4J两种方式。DOM基于Java官方标准,功能完整但代码相对复杂,适合简单场景和底层开发需求。DOM4J提供了更加简洁灵活的API,支持XPath查询,在实际项目中使用更加广泛。

选择XML解析方案时,需要综合考虑XML文件大小、项目依赖要求、开发效率以及安全性。对于普通业务系统的数据解析,DOM4J通常是更高效的选择;对于需要完全基于JDK实现的场景,DOM依然是一种可靠方案。