乐途乐途
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
    • HTTP协议
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • MyBatis
    • Spring
    • Spring MVC
    • Maven 入门
    • Maven 进阶
    • Java 设计模式
  • 缓存

    • Redis
联系
阿里云
  • 学习路径
  • XML 基础语法

    • XML 概述
    • XML 文档结构
    • XML 元素
    • XML 属性
    • XML 语法规则
    • XML 命名空间
    • XML 注释与处理指令
  • DTD 与文档验证

    • DTD 概述
    • DTD 元素声明
    • DTD 属性声明
    • DTD 实体声明
    • DTD 元素与属性对比
    • DTD 完整示例
  • XML Schema 定义

    • XML Schema 概述
    • XSD 简单类型
    • XSD 复杂类型
    • XSD 命名空间与引用
  • XPath 节点定位

    • XPath 概述
    • XPath 路径表达式
    • XPath 谓词与函数
  • XSLT 转换

    • XSLT 概述
    • XSLT 模板与匹配
    • XSLT 控制结构
    • XSLT 输出控制
  • XML 解析技术

    • XML 解析概述
    • DOM 解析
    • SAX 解析
    • StAX 解析
    • XML 与 Java — JAXP
  • XML 在 Java 中的应用

    • Spring XML 配置
    • MyBatis XML 映射
    • pom.xml 与 Maven
    • web.xml 配置详解
  • 现代数据格式对比

    • XML 与 JSON 对比
    • XML 与 YAML 对比
  • XML 显示与浏览器集成

    • XML 在浏览器中的显示
    • XMLHttpRequest 与 AJAX
    • 服务器端 XML 处理
  • XML 进阶查询与链接

    • XQuery 查询语言
    • XLink 超链接
    • XML 验证工具使用
  • XML Web 服务(选读)

    • XML Web 服务概述
    • SOAP 协议详解
    • WSDL 服务描述
    • RSS 内容聚合
    • RDF 资源描述框架

DOM 解析

本章定位 :掌握 DOM(Document Object Model)解析——树构建过程、核心 API(Document/Element/NodeList)、导航方法和增删改操作。

定义与作用

DOM (Document Object Model)是 W3C 标准,将 XML/HTML 文档表示为内存中的 节点树 。解析器读取整个 XML 文档,构建一棵完整的树,然后程序可以在树上执行任意操作——遍历、查询、修改、删除、新增。

DOM 是"重量级"方案:它的代价是内存(整棵树驻留内存),回报是最大的灵活性(任何节点随时访问,任何位置随时修改)。

核心原理:从 XML 到 DOM 树

图解释 :DOM 解析器将 XML 文本解析为节点树。每种 XML 结构对应一种节点类型(Document / Element / Text / Attr)。构建完成后,通过 API 进行导航、查找和修改。

语法/结构要点

核心接口

接口作用常用方法
Document整个文档的根getDocumentElement() createElement() getElementsByTagName()
Element元素节点getAttribute() setAttribute() getElementsByTagName() appendChild() removeChild()
Node所有节点基类getNodeName() getNodeValue() getChildNodes() getParentNode()
NodeList节点集合item(index) getLength()
Text文本节点getData() setData()

导航方法

方法/属性返回说明
getChildNodes()NodeList所有子节点(包括文本和注释)
getFirstChild()Node第一个子节点
getLastChild()Node最后一个子节点
getParentNode()Node父节点
getNextSibling()Node下一个兄弟节点
getElementsByTagName(name)NodeList按标签名查找(递归)

完整示例:小崔用 DOM 管理学生信息

场景说明

飞翔科技的后端 小崔 负责学生管理系统。需求:①统计学生数量;②给所有 2023 级学生加一个 batch 属性;③删除 GPA 低于 2.0 的学生。

XML 数据

<?xml version="1.0" encoding="UTF-8"?>
<students>
  <student id="S001" enrollYear="2023">
    <name>小崔</name>
    <gpa>3.8</gpa>
  </student>
  <student id="S002" enrollYear="2023">
    <name>阿呆</name>
    <gpa>1.5</gpa>
  </student>
  <student id="S003" enrollYear="2024">
    <name>黄俪</name>
    <gpa>3.5</gpa>
  </student>
</students>

Java DOM 操作

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import java.io.File;

public class StudentManager {
    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new File("students.xml"));

        // ① 统计学生数
        NodeList students = doc.getElementsByTagName("student");
        System.out.println("学生总数: " + students.getLength());

        // ② 给 2023 级学生加 batch="2023A"
        for (int i = 0; i < students.getLength(); i++) {
            Element student = (Element) students.item(i);
            if ("2023".equals(student.getAttribute("enrollYear"))) {
                student.setAttribute("batch", "2023A");
            }
        }

        // ③ 删除 GPA < 2.0 的学生
        // 注意:不能在遍历 NodeList 时直接删除(会改变列表)
        // 用父节点收集待删除列表
        Element root = doc.getDocumentElement();
        NodeList toDelete = doc.getElementsByTagName("gpa");
        for (int i = 0; i < toDelete.getLength(); i++) {
            Element gpaElem = (Element) toDelete.item(i);
            double gpa = Double.parseDouble(gpaElem.getTextContent());
            if (gpa < 2.0) {
                Node studentNode = gpaElem.getParentNode();
                root.removeChild(studentNode);
                System.out.println("已删除低GPA学生");
            }
        }

        // ④ 保存修改后的文档
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.transform(
            new DOMSource(doc),
            new StreamResult(new File("students_updated.xml"))
        );

        System.out.println("修改已保存到 students_updated.xml");
    }
}

操作结果

学生总数: 3
已删除低GPA学生
修改已保存到 students_updated.xml

修改后的 XML:

<students>
  <student batch="2023A" enrollYear="2023" id="S001">
    <name>小崔</name><gpa>3.8</gpa>
  </student>
  <student enrollYear="2024" id="S003">
    <name>黄俪</name><gpa>3.5</gpa>
  </student>
</students>

阿呆(GPA=1.5)被移除,2023 级的小崔多了 batch 属性。

易错场景

错误一:遍历时直接删除节点导致 IndexOutOfBounds

// ❌ NodeList 是动态的,删除会改变长度
for (int i = 0; i < students.getLength(); i++) {
    root.removeChild(students.item(i));
}

正确做法:收集待删除节点,循环结束后再删除;或倒序遍历。

错误二:忘记保存修改

DOM 修改的是内存中的树,必须用 Transformer 写回文件,否则修改丢失。

面试考点

考点参考答案要点
DOM 解析的工作流程?①创建 DocumentBuilderFactory → ②创建 DocumentBuilder → ③parse() 构建内存中的 Document 树 → ④通过 DOM API 操作节点树 → ⑤Transformer 写回文件
DOM 的优缺点?优点:支持随机访问和修改,API 直观。缺点:全文档驻留内存,大文档导致 OOM
getElementsByTagName 和 getChildNodes 的区别?getElementsByTagName 递归搜索所有后代;getChildNodes 只返回直接子节点(包括空白文本节点)
上一页
XML 解析概述
下一页
SAX 解析