Java对XML文件的解析、节点的增加、删除操作总结
XML作为常用的数据交换格式,在很多系统中都有广泛应用。Java生态中提供了多种XML处理方式,本文将以JDK自带的DOM解析方式为例,详细介绍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>30</age>
<email>lisi@ipipp.com</email>
</user>
</users>我们将基于这个文件完成后续的解析、新增、删除操作,操作完成后会将修改后的内容回写到XML文件中。
二、XML解析操作
DOM解析的核心思路是将整个XML文档加载到内存中,形成一棵节点树,然后我们可以通过节点之间的关系遍历获取需要的内容。下面是完整的解析示例:
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
public class XmlParseDemo {
public static void main(String[] args) {
try {
// 1. 创建解析器工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 2. 创建解析器
DocumentBuilder builder = factory.newDocumentBuilder();
// 3. 解析XML文件,得到Document对象(整个XML的树模型)
Document document = builder.parse(new File("test.xml"));
// 4. 获取根节点users
Element root = document.getDocumentElement();
System.out.println("根节点名称:" + root.getNodeName());
// 5. 获取所有user节点
NodeList userNodes = root.getElementsByTagName("user");
System.out.println("总共有" + userNodes.getLength() + "个用户节点");
// 6. 遍历所有user节点,输出节点信息
for (int i = 0; i < userNodes.getLength(); i++) {
Node userNode = userNodes.item(i);
if (userNode.getNodeType() == Node.ELEMENT_NODE) {
Element userElement = (Element) userNode;
// 获取user节点的id属性
String userId = userElement.getAttribute("id");
System.out.println("\n用户ID:" + userId);
// 获取name子节点内容
String name = userElement.getElementsByTagName("name").item(0).getTextContent();
// 获取age子节点内容
String age = userElement.getElementsByTagName("age").item(0).getTextContent();
// 获取email子节点内容
String email = userElement.getElementsByTagName("email").item(0).getTextContent();
System.out.println("姓名:" + name);
System.out.println("年龄:" + age);
System.out.println("邮箱:" + email);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}上述代码执行后,会输出XML中所有的用户信息。需要注意的点:
- DocumentBuilderFactory和DocumentBuilder是JDK自带的类,无需额外引入依赖
- getElementsByTagName方法返回的是所有匹配标签名的节点集合,哪怕只有一个节点也需要通过item(0)获取
- getTextContent()方法可以直接获取节点及其所有子节点的文本内容,对于叶子节点来说就是节点的值
三、XML节点新增操作
新增节点的核心步骤是创建新节点、设置节点属性和内容、将新节点挂载到父节点下,最后将更新后的Document对象回写到XML文件。下面是新增一个用户节点的示例:
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
public class XmlAddNodeDemo {
public static void main(String[] args) {
try {
// 1. 解析原有XML文件,获取Document对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("test.xml"));
Element root = document.getDocumentElement();
// 2. 创建新的user节点
Element newUser = document.createElement("user");
// 设置user节点的id属性
newUser.setAttribute("id", "3");
// 3. 创建user节点下的子节点并设置内容
Element nameNode = document.createElement("name");
nameNode.setTextContent("王五");
Element ageNode = document.createElement("age");
ageNode.setTextContent("28");
Element emailNode = document.createElement("email");
emailNode.setTextContent("wangwu@ipipp.com");
// 4. 将子节点挂载到newUser节点下
newUser.appendChild(nameNode);
newUser.appendChild(ageNode);
newUser.appendChild(emailNode);
// 5. 将新的user节点挂载到根节点下
root.appendChild(newUser);
// 6. 将更新后的Document对象回写到XML文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// 设置输出格式,保留XML声明和缩进
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File("test.xml"));
transformer.transform(source, result);
System.out.println("新用户节点添加成功,已回写到test.xml文件");
} catch (Exception e) {
e.printStackTrace();
}
}
}执行上述代码后,test.xml中会新增一个id为3的用户节点。这里需要注意Transformer的输出属性设置,如果不设置缩进,回写后的XML文件会没有格式,所有内容挤在一行。
四、XML节点删除操作
删除节点的核心是先找到目标节点,然后通过父节点的removeChild方法移除该节点,最后同样回写文件。下面示例删除id为2的用户节点:
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
public class XmlDeleteNodeDemo {
public static void main(String[] args) {
try {
// 1. 解析XML文件,获取Document对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("test.xml"));
Element root = document.getDocumentElement();
// 2. 获取所有user节点,遍历找到要删除的目标节点
NodeList userNodes = root.getElementsByTagName("user");
Node targetNode = null;
for (int i = 0; i < userNodes.getLength(); i++) {
Node userNode = userNodes.item(i);
if (userNode.getNodeType() == Node.ELEMENT_NODE) {
Element userElement = (Element) userNode;
String userId = userElement.getAttribute("id");
// 找到id为2的用户节点
if ("2".equals(userId)) {
targetNode = userNode;
break;
}
}
}
// 3. 如果找到目标节点,执行删除操作
if (targetNode != null) {
// 通过父节点删除子节点
root.removeChild(targetNode);
System.out.println("id为2的用户节点删除成功");
} else {
System.out.println("未找到id为2的用户节点");
}
// 4. 将更新后的Document对象回写到XML文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new File("test.xml"));
transformer.transform(source, result);
System.out.println("修改已回写到test.xml文件");
} catch (Exception e) {
e.printStackTrace();
}
}
}执行上述代码后,test.xml中id为2的用户节点会被删除。这里需要注意,删除节点必须通过其父节点调用removeChild方法,不能直接调用节点自身的删除方法,DOM中节点没有自删除的接口。
五、注意事项总结
- DOM解析方式会将整个XML加载到内存,适合处理较小的XML文件,大文件建议使用SAX或者StAX方式
- 所有的修改操作完成后,必须执行回写操作才能将改动保存到文件中,否则只是内存中的Document对象发生了变化
- 操作节点属性时使用getAttribute和setAttribute方法,操作节点文本内容时使用getTextContent和setTextContent方法
- 遍历节点时建议先判断节点类型,避免获取到空白文本节点导致空指针异常
Java XML解析DOM操作节点增删DocumentBuilderTransformer 本作品最后修改时间:2026-05-22 21:28:53