DOM即文档对象模型,是W3C制定的标准接口规范,它将XML文档转换为树形结构存放在内存中,开发者可以通过操作内存中的树节点来读取、修改XML内容,这种方式逻辑清晰,适合处理结构相对简单的XML文件。

DOM解析XML的核心步骤
使用Java自带的DOM解析器处理XML文件,整体流程可以分为以下几个环节:
- 创建文档构建器工厂实例
- 通过工厂获取文档构建器对象
- 加载目标XML文件生成Document对象
- 通过Document对象获取根节点,再递归或遍历获取子节点内容
- 处理完成后释放相关资源
完整代码示例
假设我们有如下结构的XML文件,路径为src/main/resources/user.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>
下面是使用DOM方式解析该XML文件的Java代码:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
public class DomXmlParser {
public static void main(String[] args) {
try {
// 1. 创建文档构建器工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 2. 获取文档构建器
DocumentBuilder builder = factory.newDocumentBuilder();
// 3. 加载XML文件,生成Document对象
// 这里使用类加载器获取resources目录下的XML文件输入流
InputStream inputStream = DomXmlParser.class.getClassLoader().getResourceAsStream("user.xml");
Document document = builder.parse(inputStream);
// 4. 获取根节点
Element rootElement = document.getDocumentElement();
System.out.println("根节点名称:" + rootElement.getNodeName());
// 5. 获取所有user子节点
NodeList userNodes = rootElement.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;
// 获取user节点的id属性
String userId = userElement.getAttribute("id");
System.out.println("用户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 + ",年龄:" + age + ",邮箱:" + email);
System.out.println("-------------------");
}
}
// 关闭输入流
if (inputStream != null) {
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码关键说明
上述代码中需要注意几个点:
- DocumentBuilderFactory是线程不安全的,建议每次使用时单独创建实例,不要作为全局静态变量使用
- 获取节点内容时,需要先判断节点类型,避免获取到空白文本节点导致错误
- 如果XML文件较大,DOM解析会将整个文档加载到内存,可能造成内存溢出,此时需要考虑其他解析方式
DOM解析的优缺点
优点
- API简单易用,符合树形结构的操作逻辑,容易理解
- 可以随机访问文档中的任意节点,支持修改XML内容后重新输出
- 是Java标准库自带的功能,不需要额外引入第三方依赖
缺点
- 需要将整个XML文档加载到内存,不适合处理超大XML文件
- 内存占用较高,解析效率相比SAX等方式更低
常见问题处理
如果解析时出现org.xml.sax.SAXParseException异常,通常是XML文件格式不规范导致,比如标签没有正确闭合、属性值没有加引号等,可以先使用XML校验工具检查文件格式。如果XML文件包含特殊字符,需要确保文件编码和解析时指定的编码一致,默认使用UTF-8编码即可。