XML文件怎么实现增删改操作?

来源:IPIPP.com作者:头衔:全栈工程师
导读:本期聚焦于小伙伴创作的《XML文件怎么实现增删改操作?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《XML文件怎么实现增删改操作?》有用,将其分享出去将是对创作者最好的鼓励。

XML(可扩展标记语言)凭借其结构清晰、跨平台兼容的特性,在配置文件存储、数据交换等场景中应用广泛。在实际开发中,我们经常会遇到需要修改XML文件内容的需求,比如新增节点、删除冗余配置、更新节点属性等。不同的XML解析方式实现增删改的逻辑存在差异,选择合适的解析工具能让开发效率大幅提升。

XML文件怎么实现增删改操作?

XML解析方式对比

常见的XML解析方式主要分为DOM解析、SAX解析、JDOM解析和DOM4J解析四种,不同方式的特性适合不同的操作场景:

解析方式原理优点缺点适用场景
DOM解析将整个XML文档加载到内存,形成树形结构支持随机访问,可方便实现增删改操作文档过大时内存占用高小到中型XML文件的修改操作
SAX解析基于事件驱动,边读边解析,不加载整个文档内存占用低,解析速度快只能顺序读取,不支持修改操作大型XML文件的只读解析
JDOM解析基于DOM改进,使用Java集合类简化操作API更符合Java开发习惯性能略低于DOM4JJava项目中简单的XML操作
DOM4J解析基于JDOM优化,性能和灵活性更优支持XPath查询,API丰富,操作便捷需要额外导入依赖包复杂XML增删改场景,推荐使用

如果需要对XML进行增删改操作,DOM和DOM4J是优先选择,其中DOM4J的API更简洁,还支持XPath快速定位节点,实际开发中应用最多。本文后续示例都将基于DOM4J展开。

环境准备

使用DOM4J需要先导入对应的依赖包,如果是Maven项目,在pom.xml中添加如下依赖:

<dependency>
    <groupId>org.dom4j</groupId>
    <artifactId>dom4j</artifactId>
    <version>2.1.4</version>
</dependency>
<!-- 如果需要使用XPath,还需要添加jaxen依赖 -->
<dependency>
    <groupId>jaxen</groupId>
    <artifactId>jaxen</artifactId>
    <version>1.2.0</version>
</dependency>

如果是普通Java项目,可以手动下载dom4j和jaxen的jar包,导入到项目的类路径中即可。

XML增删改操作实现

我们先准备一个测试用的XML文件,命名为test.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user id="1">
        <name>张三</name>
        <age>25</age>
        <email>zhangsan@ipipp.com</email>
    </user>
    <user id="2">
        <name>李四</name>
        <age>28</age>
        <email>lisi@ipipp.com</email>
    </user>
</users>

1. 新增XML节点

新增节点分为两种情况:在指定父节点下新增子节点,以及在指定位置插入节点。下面演示在users根节点下新增一个user子节点:

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class XmlAddDemo {
    public static void main(String[] args) throws DocumentException, IOException {
        // 1. 创建SAXReader读取XML文件
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("test.xml"));
        // 2. 获取根节点
        Element rootElement = document.getRootElement();
        // 3. 新增user节点,并设置属性
        Element newUser = rootElement.addElement("user");
        newUser.addAttribute("id", "3");
        // 4. 新增user下的子节点
        Element name = newUser.addElement("name");
        name.setText("王五");
        Element age = newUser.addElement("age");
        age.setText("30");
        Element email = newUser.addElement("email");
        email.setText("wangwu@ipipp.com");
        // 5. 设置输出格式,避免中文乱码,格式化输出
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        // 6. 写入文件
        XMLWriter writer = new XMLWriter(new FileOutputStream("test.xml"), format);
        writer.write(document);
        writer.close();
        System.out.println("新增节点成功");
    }
}

运行上述代码后,test.xml中会增加一个id为3的用户节点。如果需要在指定位置插入节点,可以先获取父节点的所有子节点列表,再调用add(int index, Element element)方法插入,示例代码如下:

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class XmlInsertDemo {
    public static void main(String[] args) throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("test.xml"));
        Element rootElement = document.getRootElement();
        // 获取所有user子节点
        List<Element> userList = rootElement.elements("user");
        // 创建要插入的新节点
        Element insertUser = rootElement.createElement("user");
        insertUser.addAttribute("id", "1.5");
        Element name = insertUser.addElement("name");
        name.setText("赵六");
        Element age = insertUser.addElement("age");
        age.setText("26");
        Element email = insertUser.addElement("email");
        email.setText("zhaoliu@ipipp.com");
        // 在第二个位置(索引1)插入新节点
        userList.add(1, insertUser);
        // 重新整理根节点的子节点顺序
        rootElement.clearContent();
        for (Element user : userList) {
            rootElement.add(user);
        }
        // 写入文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("test.xml"), format);
        writer.write(document);
        writer.close();
        System.out.println("插入节点到指定位置成功");
    }
}

2. 修改XML节点

修改XML节点通常需要先定位到目标节点,再修改其属性或文本内容。结合XPath可以快速定位节点,比如修改id为2的用户的年龄:

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.xpath.DefaultXPath;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class XmlUpdateDemo {
    public static void main(String[] args) throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("test.xml"));
        // 使用XPath定位id为2的user节点
        DefaultXPath xPath = new DefaultXPath("//user[@id='2']");
        List<Element> nodes = xPath.selectNodes(document);
        if (nodes != null && !nodes.isEmpty()) {
            Element targetUser = nodes.get(0);
            // 修改age子节点的文本
            Element ageElement = targetUser.element("age");
            if (ageElement != null) {
                ageElement.setText("29");
            }
            // 修改user节点的属性
            targetUser.addAttribute("id", "2"); // 如果要修改属性值,直接设置即可,会覆盖原有值
            targetUser.addAttribute("status", "active"); // 新增属性
        }
        // 写入文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("test.xml"), format);
        writer.write(document);
        writer.close();
        System.out.println("修改节点成功");
    }
}

如果没有使用XPath,也可以通过遍历所有节点来定位目标节点,适合结构简单的XML文件:

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

public class XmlUpdateDemo2 {
    public static void main(String[] args) throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("test.xml"));
        Element rootElement = document.getRootElement();
        // 遍历所有user节点
        Iterator<Element> userIterator = rootElement.elementIterator("user");
        while (userIterator.hasNext()) {
            Element user = userIterator.next();
            String id = user.attributeValue("id");
            if ("2".equals(id)) {
                // 找到目标节点,修改内容
                Element nameElement = user.element("name");
                if (nameElement != null) {
                    nameElement.setText("李四更新");
                }
                break;
            }
        }
        // 写入文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("test.xml"), format);
        writer.write(document);
        writer.close();
        System.out.println("遍历修改节点成功");
    }
}

3. 删除XML节点

删除节点同样需要先定位到目标节点,再调用父节点的remove(Element element)方法删除。下面演示删除id为1.5的用户节点:

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.dom4j.xpath.DefaultXPath;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

public class XmlDeleteDemo {
    public static void main(String[] args) throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("test.xml"));
        // 使用XPath定位要删除的节点
        DefaultXPath xPath = new DefaultXPath("//user[@id='1.5']");
        List<Element> nodes = xPath.selectNodes(document);
        if (nodes != null && !nodes.isEmpty()) {
            Element targetUser = nodes.get(0);
            // 获取父节点,调用remove方法删除
            Element parent = targetUser.getParent();
            if (parent != null) {
                parent.remove(targetUser);
            }
        }
        // 写入文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("test.xml"), format);
        writer.write(document);
        writer.close();
        System.out.println("删除节点成功");
    }
}

如果要删除节点的某个属性或者子节点,也可以直接调用对应节点的remove方法:

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class XmlDeleteAttrDemo {
    public static void main(String[] args) throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(new File("test.xml"));
        Element rootElement = document.getRootElement();
        // 遍历user节点,删除status属性
        Iterator<Element> userIterator = rootElement.elementIterator("user");
        while (userIterator.hasNext()) {
            Element user = userIterator.next();
            // 删除status属性
            user.remove(user.attribute("status"));
            // 删除age子节点
            Element age = user.element("age");
            if (age != null) {
                user.remove(age);
            }
        }
        // 写入文件
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("test.xml"), format);
        writer.write(document);
        writer.close();
        System.out.println("删除属性和子节点成功");
    }
}

注意事项

  • 操作XML文件前建议先备份原文件,避免修改出错导致数据丢失。
  • 写入文件时要设置正确的编码格式,否则容易出现中文乱码问题,通常XML文件使用UTF-8编码。
  • 使用DOM4J操作大文件时,如果文件超过内存限制,建议分块处理,或者改用SAX解析后生成新的XML文件。
  • XPath表达式要注意语法的正确性,如果定位不到节点,可以先打印所有节点信息排查问题。
  • 修改属性时,如果属性已存在,直接调用addAttribute会覆盖原有值,不需要先删除再添加。

总结

XML的增删改操作核心是先通过解析工具将XML加载为内存中的文档对象,再通过API操作对应的节点,最后将修改后的文档写回文件。DOM4J作为目前最常用的XML解析工具,兼顾了性能和易用性,配合XPath可以快速定位节点,大幅提升开发效率。实际开发中可以根据XML文件的大小和操作复杂度,选择合适的解析方式和实现逻辑,同时注意编码和备份等细节问题,就能顺利完成XML内容的修改需求。

XMLXML解析DOM4JXPath修改时间:2026-05-24 22:11:28

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