XML DOM 教程(长文讲解)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言

在数据处理与信息交换的领域中,XML(可扩展标记语言)凭借其结构化和跨平台的优势,成为众多开发者的重要工具。而DOM(文档对象模型)则是操作XML文档的核心接口。无论是解析配置文件、处理API返回的数据,还是构建动态内容生成系统,掌握XML DOM 技能都能显著提升开发效率。本文将从基础概念出发,结合实例代码,逐步解析如何高效使用DOM技术操作XML文档,帮助开发者快速入门并进阶。


一、XML DOM 的基础概念

1.1 XML:数据的“结构化容器”

XML通过自定义标签将数据封装为树形结构,例如:

<bookstore>  
  <book category="fiction">  
    <title>1984</title>  
    <author>George Orwell</author>  
    <price>12.99</price>  
  </book>  
</bookstore>  

这里的<bookstore>是根元素,包含多个<book>子元素,每个元素可以携带属性(如category="fiction")和文本内容。这种结构化设计让数据易于解析和扩展。

比喻:XML就像一个“图书馆目录系统”,每个标签代表一本书的分类、作者、价格等信息,通过层级关系清晰表达数据关联。

1.2 DOM:XML文档的“导航地图”

DOM将XML文档解析为内存中的树状对象,每个节点(Node)代表文档中的一个元素、属性或文本。开发者可以通过DOM API遍历节点、查询特定元素、修改内容,甚至动态生成新节点。

核心概念对比
| 概念 | 解释 | 类比说明 |
|------------|----------------------------------------|------------------------------|
| 节点(Node)| 文档中的最小组成单元,如元素、文本等 | 图书馆中的每本书或书架标签 |
| 元素(Element)| 具有标签名的节点,如<book> | 图书分类标签 |
| 属性(Attribute)| 元素的附加信息,如category="fiction" | 书本的ISBN编号或出版日期 |
| 文本节点 | 包含纯文本内容的节点,如"1984" | 书名、价格等具体信息 |


二、DOM 核心操作:从加载到修改

2.1 加载XML文档

在JavaScript中,可通过DOMParser解析XML字符串;在Python中,xml.etree.ElementTree模块提供类似功能。

JavaScript示例

const xmlString = `  
<bookstore>  
  <book category="fiction">  
    <title>1984</title>  
    <price>12.99</price>  
  </book>  
</bookstore>`;  

const parser = new DOMParser();  
const xmlDoc = parser.parseFromString(xmlString, "application/xml");  

Python示例

import xml.etree.ElementTree as ET  

xml_data = """  
<bookstore>  
  <book category="fiction">  
    <title>1984</title>  
    <price>12.99</price>  
  </book>  
</bookstore>  
"""  

root = ET.fromstring(xml_data)  

2.2 遍历节点:探索文档的“树枝”

DOM树的遍历可通过父子关系逐层访问节点。例如,获取所有<book>元素:

JavaScript示例

// 获取根节点下的所有book元素  
const books = xmlDoc.getElementsByTagName("book");  

for (let i = 0; i < books.length; i++) {  
  console.log(books[i].getAttribute("category"));  // 获取属性值  
  const title = books[i].getElementsByTagName("title")[0].textContent;  
  console.log(title);  
}  

2.3 访问与修改数据

通过DOM API可直接读取或修改节点内容:

修改节点文本

// 将第一本书的价格改为15.99  
const firstBook = xmlDoc.querySelector("book");  
const priceNode = firstBook.querySelector("price");  
priceNode.textContent = "15.99";  

添加新节点

// 创建新书元素  
const newBook = xmlDoc.createElement("book");  
newBook.setAttribute("category", "non-fiction");  

const newTitle = xmlDoc.createElement("title");  
newTitle.textContent = "Sapiens";  

newBook.appendChild(newTitle);  
xmlDoc.querySelector("bookstore").appendChild(newBook);  

三、实战案例:解析RSS订阅源

3.1 场景描述

假设需要从RSS源(如博客文章列表)提取标题、链接和发布日期,DOM操作可轻松实现这一需求。

示例RSS片段

<rss>  
  <channel>  
    <item>  
      <title>Understanding XML DOM</title>  
      <link>https://example.com/post/1</link>  
      <pubDate>2023-01-15</pubDate>  
    </item>  
    <item>  
      <title>Advanced JavaScript Tips</title>  
      <link>https://example.com/post/2</link>  
      <pubDate>2023-01-16</pubDate>  
    </item>  
  </channel>  
</rss>  

3.2 JavaScript解析代码

// 假设rssXml是解析后的DOM对象  
const items = rssXml.getElementsByTagName("item");  

const articles = [];  
for (let i = 0; i < items.length; i++) {  
  const item = items[i];  
  const title = item.querySelector("title").textContent;  
  const link = item.querySelector("link").textContent;  
  const date = item.querySelector("pubDate").textContent;  

  articles.push({ title, link, date });  
}  

console.log(articles);  
// 输出:  
// [  
//   { title: "Understanding XML DOM", link: "...", date: "2023-01-15" },  
//   ...  
// ]  

3.3 动态生成HTML展示

将解析后的数据渲染到网页:

const outputDiv = document.getElementById("output");  

articles.forEach(article => {  
  const div = document.createElement("div");  
  div.innerHTML = `  
    <h3>${article.title}</h3>  
    <a href="${article.link}">Read more</a>  
    <p>Published on ${article.date}</p>  
  `;  
  outputDiv.appendChild(div);  
});  

四、高级技巧:命名空间与事件处理

4.1 处理命名空间

当XML文档包含命名空间时(如xmlns="http://example.com"),需通过前缀或URI定位元素。

JavaScript示例

// 带命名空间的XML  
const xmlNS = `  
<feed xmlns="http://www.w3.org/2005/Atom">  
  <entry>  
    <title>Sample Entry</title>  
  </entry>  
</feed>`;  

const parser = new DOMParser();  
const xmlDoc = parser.parseFromString(xmlNS, "application/xml");  

// 使用命名空间URI查询元素  
const entries = xmlDoc.querySelectorAll("entry",  
  xmlDoc.lookupNamespaceURI(""));  // 空前缀获取默认命名空间  

entries.forEach(entry => {  
  console.log(entry.querySelector("title").textContent);  
});  

4.2 监听DOM变更事件

通过MutationObserver可实时监控DOM结构变化:

const observer = new MutationObserver((mutations) => {  
  mutations.forEach(mutation => {  
    if (mutation.type === "childList") {  
      console.log("Node added or removed!");  
    }  
  });  
});  

// 开始监听根节点的子节点变化  
observer.observe(xmlDoc.documentElement, { childList: true });  

结论

通过本文的讲解,开发者应已掌握XML DOM 的核心操作:从加载文档到遍历、查询、修改节点,再到实战案例中的RSS解析与动态渲染。DOM技术不仅适用于传统Web开发,也是处理配置文件、构建API数据解析工具的重要基础。

对于初学者,建议从简单案例入手,逐步尝试修改节点结构或结合前端框架动态展示数据;中级开发者可探索命名空间、性能优化(如减少DOM操作频率)等进阶主题。记住,DOM就像一座“数据桥梁”,它连接着静态的XML结构与动态的程序逻辑——掌握这座桥梁的“建造”与“导航”技能,将为你的开发之路增添更多可能性。

下一步行动:选择一个真实XML文件(如公开的RSS源或配置文件),尝试用本文中的代码片段进行解析和修改,通过实践巩固知识。

最新发布