XML(可扩展标记语言)常用于配置文件、数据交换场景,对XML文件进行增删改查是开发中的常见需求,本文使用Java的DOM解析方式实现相关操作,DOM方式会将XML整体加载到内存形成树结构,操作直观便于理解。

XML增删改查前置准备
首先准备一个初始的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>
操作XML前需要导入相关的Java类库,DOM解析相关的类都在javax.xml.parsers、org.w3c.dom、javax.xml.transform包下,JDK默认已经包含这些类库,无需额外引入依赖。
XML查询操作实现
查询操作是读取XML中指定节点的内容,比如查询所有用户的信息,或者根据id查询指定用户的信息,实现步骤如下:
- 创建DocumentBuilderFactory实例,获取DocumentBuilder
- 解析XML文件得到Document对象
- 通过标签名或者属性获取对应的节点
- 读取节点的文本内容或者属性值
查询所有用户信息的代码示例如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
public class XMLQueryDemo {
public static void main(String[] args) throws Exception {
// 创建解析工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 获取解析器
DocumentBuilder builder = factory.newDocumentBuilder();
// 解析XML文件得到Document对象
Document document = builder.parse("users.xml");
// 获取所有user节点
NodeList userNodes = document.getElementsByTagName("user");
// 遍历所有user节点
for (int i = 0; i < userNodes.getLength(); i++) {
Node userNode = userNodes.item(i);
if (userNode.getNodeType() == Node.ELEMENT_NODE) {
Element userElement = (Element) userNode;
// 获取id属性
String id = userElement.getAttribute("id");
// 获取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("用户ID:" + id + ",姓名:" + name + ",年龄:" + age + ",邮箱:" + email);
}
}
}
}
XML新增操作实现
新增操作是在XML中添加新的节点,比如新增一个用户节点,实现步骤如下:
- 解析原有XML得到Document对象
- 创建新的元素节点和文本节点
- 将文本节点添加到对应的元素节点中
- 将新创建的元素节点添加到父节点中
- 将修改后的Document对象写回XML文件
新增一个id为3的用户节点代码示例如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class XMLAddDemo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("users.xml");
// 获取根节点users
Element rootElement = document.getDocumentElement();
// 创建新的user节点
Element newUser = document.createElement("user");
// 设置id属性
newUser.setAttribute("id", "3");
// 创建name节点
Element nameElement = document.createElement("name");
nameElement.setTextContent("王五");
// 创建age节点
Element ageElement = document.createElement("age");
ageElement.setTextContent("30");
// 创建email节点
Element emailElement = document.createElement("email");
emailElement.setTextContent("wangwu@ipipp.com");
// 将子节点添加到user节点
newUser.appendChild(nameElement);
newUser.appendChild(ageElement);
newUser.appendChild(emailElement);
// 将user节点添加到根节点
rootElement.appendChild(newUser);
// 将修改后的内容写回XML文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult("users.xml");
transformer.transform(source, result);
System.out.println("新增用户成功");
}
}
XML修改操作实现
修改操作是更新XML中已有节点的内容或者属性,比如修改id为2的用户的年龄为29,实现步骤如下:
- 解析XML得到Document对象
- 定位到需要修改的节点
- 修改节点的文本内容或者属性值
- 将修改后的Document对象写回XML文件
修改指定用户信息的代码示例如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
public class XMLUpdateDemo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("users.xml");
// 获取所有user节点
NodeList userNodes = document.getElementsByTagName("user");
for (int i = 0; i < userNodes.getLength(); i++) {
Node userNode = userNodes.item(i);
if (userNode.getNodeType() == Node.ELEMENT_NODE) {
Element userElement = (Element) userNode;
// 找到id为2的用户
if ("2".equals(userElement.getAttribute("id"))) {
// 修改age节点的内容
Element ageElement = (Element) userElement.getElementsByTagName("age").item(0);
ageElement.setTextContent("29");
// 修改email内容
Element emailElement = (Element) userElement.getElementsByTagName("email").item(0);
emailElement.setTextContent("lisi_new@ipipp.com");
break;
}
}
}
// 写回XML文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult("users.xml");
transformer.transform(source, result);
System.out.println("修改用户成功");
}
}
XML删除操作实现
删除操作是移除XML中指定的节点,比如删除id为1的用户节点,实现步骤如下:
- 解析XML得到Document对象
- 定位到需要删除的节点
- 通过父节点移除该节点
- 将修改后的Document对象写回XML文件
删除指定用户节点的代码示例如下:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
public class XMLDeleteDemo {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("users.xml");
NodeList userNodes = document.getElementsByTagName("user");
for (int i = 0; i < userNodes.getLength(); i++) {
Node userNode = userNodes.item(i);
if (userNode.getNodeType() == Node.ELEMENT_NODE) {
Element userElement = (Element) userNode;
// 找到id为1的用户
if ("1".equals(userElement.getAttribute("id"))) {
// 通过父节点移除当前用户节点
userNode.getParentNode().removeChild(userNode);
break;
}
}
}
// 写回XML文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult("users.xml");
transformer.transform(source, result);
System.out.println("删除用户成功");
}
}
操作注意事项
- DOM方式会将整个XML加载到内存,如果XML文件过大,可能会导致内存占用过高,此时可以考虑使用SAX解析方式
- 写回XML文件时需要设置编码,避免中文乱码,可以在Transformer中设置输出属性
encoding为UTF-8 - 操作XML时要注意节点的类型,避免操作到文本节点或者注释节点导致异常
- 如果XML文件路径是相对路径,默认是相对于项目的工作目录,也可以使用绝对路径指定XML文件位置