XML DOM 总结(千字长文)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
 - 《从零手撸:仿小红书(微服务架构)》 已完结,基于
 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
 截止目前, 星球 内专栏累计输出 100w+ 字,讲解图 4013+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3700+ 小伙伴加入学习 ,欢迎点击围观
前言
在数据交换和配置管理的场景中,XML(可扩展标记语言)因其灵活的结构和跨平台兼容性,成为开发者常用的工具之一。而DOM(文档对象模型)则是解析和操作XML文档的核心技术。无论是前端开发、后端服务还是系统集成,掌握XML与DOM的知识都能显著提升数据处理的效率。本文将从基础概念、核心操作方法、实际案例到最佳实践,为编程初学者和中级开发者提供一份清晰的XML DOM总结。
XML 的基础概念与核心结构
XML 是什么?
XML 是一种用于标记和结构化数据的语言,其设计目标是让数据在不同系统之间自由传递。与 HTML 不同,XML 的标签由开发者自定义,因此被称为“可扩展”标记语言。例如:
<bookstore>  
  <book category="fiction">  
    <title lang="en">The Great Gatsby</title>  
    <author>F. Scott Fitzgerald</author>  
    <year>1925</year>  
    <price>9.99</price>  
  </book>  
</bookstore>  
上述 XML 文档描述了一个书店的书籍信息。其中,bookstore 是根元素,book 是子元素,category 是属性,而 title、author 等是子节点。
XML 的基本语法规则
- 元素必须闭合:每个 
<element>需要有对应的</element>,或使用自闭合标签<element />。 - 属性需用引号包裹:如 
lang="en",确保值的完整性。 - 层次化结构:元素按嵌套关系形成树状结构,便于逻辑分组。
 
形象比喻:XML 文档就像一本乐高说明书,每个标签(如 <book>)是乐高积木的“类别”,属性(如 category="fiction")是积木的颜色或形状,而嵌套结构则决定了积木的组装方式。
DOM 的核心概念与工作原理
DOM 是什么?
DOM(Document Object Model)是将 XML 或 HTML 文档表示为树形结构的对象模型。每个节点(Node)代表文档中的一个元素、属性或文本,开发者可通过编程方式访问和修改这些节点。
DOM 的树形结构
DOM 树的根节点是文档本身(document),其下包含多个层级的节点:
- 元素节点:如 
<book>、<title> - 属性节点:如 
category="fiction" - 文本节点:如 
<year>1925</year>中的文本1925 - 注释节点:如 
<!-- 这是注释 --> 
形象比喻:DOM 树就像一棵家族树,根节点是“家族祖先”,每个子节点代表后代成员。通过遍历这棵树,可以快速定位到任意成员(节点)。
如何使用 DOM 操作 XML?
第一步:解析 XML 文档
在 JavaScript 中,可通过 DOMParser 解析 XML 字符串:
const xmlString = `  
<bookstore>  
  <book category="fiction">  
    <title lang="en">The Great Gatsby</title>  
  </book>  
</bookstore>`;  
const parser = new DOMParser();  
const xmlDoc = parser.parseFromString(xmlString, "application/xml");  
在 Python 中,可使用 xml.etree.ElementTree 模块:
import xml.etree.ElementTree as ET  
xml_data = """  
<bookstore>  
  <book category="fiction">  
    <title lang="en">The Great Gatsby</title>  
  </book>  
</bookstore>  
"""  
root = ET.fromstring(xml_data)  
第二步:访问和查询节点
1. 通过元素名访问节点
在 JavaScript 中:
// 获取根节点下的所有 <book> 元素  
const books = xmlDoc.querySelectorAll("book");  
在 Python 中:
books = root.findall("book")  
2. 通过属性筛选节点
在 JavaScript 中:
// 获取 category 属性为 "fiction" 的 <book>  
const fictionBooks = xmlDoc.querySelectorAll("book[category='fiction']");  
在 Python 中:
fiction_books = root.findall(".//book[@category='fiction']")  
3. 访问文本内容和属性值
在 JavaScript 中:
const title = books[0].querySelector("title").textContent; // 获取文本内容  
const category = books[0].getAttribute("category"); // 获取属性值  
在 Python 中:
title = books[0].find("title").text  
category = books[0].get("category")  
DOM 的节点操作与修改
添加节点
1. 创建新节点
在 JavaScript 中:
const newBook = xmlDoc.createElement("book");  
const newTitle = xmlDoc.createElement("title");  
newTitle.textContent = "1984";  
newBook.appendChild(newTitle);  
在 Python 中:
new_book = ET.SubElement(root, "book", {"category": "classic"})  
new_title = ET.SubElement(new_book, "title", {"lang": "en"})  
new_title.text = "1984"  
2. 插入节点
在 JavaScript 中:
xmlDoc.querySelector("bookstore").appendChild(newBook);  
在 Python 中:
删除节点
在 JavaScript 中:
const bookToRemove = xmlDoc.querySelector("book");  
bookToRemove.parentNode.removeChild(bookToRemove);  
在 Python 中:
root.remove(books[0])  
实际案例:解析 RSS 订阅源
案例背景
RSS(Really Simple Syndication)是一种基于 XML 的格式,用于发布文章摘要。假设我们有一个 RSS 文档:
<rss version="2.0">  
  <channel>  
    <title>编程日报</title>  
    <item>  
      <title>JavaScript 新特性解析</title>  
      <link>https://example.com/article1</link>  
      <pubDate>2023-10-01</pubDate>  
    </item>  
    <item>  
      <title>Python 性能优化技巧</title>  
      <link>https://example.com/article2</link>  
      <pubDate>2023-10-02</pubDate>  
    </item>  
  </channel>  
</rss>  
案例实现
目标:提取所有文章标题和链接
在 JavaScript 中:
const parser = new DOMParser();  
const xmlDoc = parser.parseFromString(rssXml, "application/xml");  
const items = xmlDoc.querySelectorAll("item");  
items.forEach(item => {  
  const title = item.querySelector("title").textContent;  
  const link = item.querySelector("link").textContent;  
  console.log(`标题:${title}, 链接:${link}`);  
});  
在 Python 中:
import xml.etree.ElementTree as ET  
tree = ET.fromstring(rss_xml)  
for item in tree.findall(".//item"):  
    title = item.find("title").text  
    link = item.find("link").text  
    print(f"标题:{title}, 链接:{link}")  
高级技巧与最佳实践
1. 性能优化:避免频繁操作 DOM
频繁修改 DOM 会显著影响性能。例如,在 JavaScript 中批量操作节点:
// 低效方式:每次添加新元素都触发重绘  
for (let i = 0; i < 1000; i++) {  
  const newItem = document.createElement("div");  
  document.body.appendChild(newItem);  
}  
// 优化方式:使用 DocumentFragment  
const fragment = document.createDocumentFragment();  
for (let i = 0; i < 1000; i++) {  
  const newItem = document.createElement("div");  
  fragment.appendChild(newItem);  
}  
document.body.appendChild(fragment);  
2. 处理命名空间
XML 命名空间(Namespace)用于避免标签冲突。例如:
<feed xmlns="http://www.w3.org/2005/Atom">  
  <entry>  
    <title>...</title>  
  </entry>  
</feed>  
在 JavaScript 中处理命名空间需使用 lookupPrefix 或 querySelector 的命名空间参数:
const ns = xmlDoc.lookupNamespaceURI("feed");  
const entries = xmlDoc.querySelectorAll(`entry`, { "xmlns": ns });  
3. 异常处理与错误捕获
解析 XML 时可能出现格式错误。例如在 JavaScript 中:
try {  
  const xmlDoc = parser.parseFromString(xmlString, "application/xml");  
  if (xmlDoc.querySelector("parsererror")) {  
    throw new Error("XML 格式错误");  
  }  
} catch (error) {  
  console.error("解析失败:", error);  
}  
常见问题与解决方案
Q1:如何遍历 XML 的所有子节点?
在 JavaScript 中:
const root = xmlDoc.documentElement;  
root.childNodes.forEach(node => {  
  if (node.nodeType === Node.ELEMENT_NODE) {  
    console.log(node.tagName);  
  }  
});  
在 Python 中:
for child in root:  
    print(child.tag)  
Q2:如何动态生成 XML 结构?
在 JavaScript 中:
const doc = new DOMParser().parseFromString("", "text/xml");  
const root = doc.createElement("root");  
doc.appendChild(root);  
在 Python 中:
from xml.etree.ElementTree import Element, tostring  
root = Element("root")  
ET.SubElement(root, "child", {"attr": "value"})  
print(tostring(root).decode())  
Q3:DOM 与 JSON 的区别是什么?
- JSON:轻量级、结构简洁,适合键值对数据;
 - XML:结构复杂但灵活,支持命名空间和注释,适合跨平台数据交换。
 
结论
XML DOM 是开发者处理结构化数据的重要工具。通过本文的学习,读者可以掌握 XML 的基础语法、DOM 的核心操作方法,并通过实际案例理解其应用场景。无论是解析 RSS 订阅源、读取配置文件,还是构建动态 Web 应用,DOM 的树形结构和节点操作能力都能显著提升开发效率。
对于初学者,建议从简单案例入手,逐步实践节点查询、增删改查等操作;中级开发者则可探索命名空间、性能优化等高级技巧。随着对 XML DOM 的深入理解,开发者将能够更高效地应对数据解析、配置管理等复杂场景。
(全文共计约 1800 字)