XML DOM 教程

XML DOM 教程(完整版,中文)

XML DOM(Document Object Model,文档对象模型)是 W3C 的官方标准,用于在程序中以树形结构加载、访问、操作、修改、添加和删除 XML 数据。
最常用的语言是 JavaScript(浏览器端)和各种后端语言(如 Java、Python、C# 等)。

1. XML DOM 核心概念

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book id="1" category="编程">
    <title lang="zh">JavaScript 高级程序设计</title>
    <author>扎卡斯</author>
    <year>2020</year>
    <price>99.00</price>
  </book>
  <book id="2" category="小说">
    <title lang="en">The Great Gatsby</title>
    <author>F. Scott Fitzgerald</author>
    <year>1925</year>
    <price>28.50</price>
  </book>
</bookstore>

DOM 把上面的 XML 看成一棵树:

bookstore (元素节点)
└── book (元素节点, 属性: id="1", category="编程")
    ├── title (元素节点, 属性: lang="zh")
    │    └── "JavaScript 高级程序设计" (文本节点)
    ├── author (元素节点)
    │    └── "扎卡斯" (文本节点)
    ├── year (元素节点)
    │    └── "2020" (文本节点)
    └── price (元素节点)
         └── "99.00" (文本节点)

2. JavaScript 中使用 XML DOM(最常用)

2.1 加载 XML 字符串或文件

// 方法1:从字符串加载
const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<bookstore>...</bookstore>`;

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

// 方法2:从文件加载(现代浏览器 fetch)
fetch('books.xml')
  .then(response => response.text())
  .then(str => parser.parseFromString(str, "text/xml"))
  .then(xmlDoc => {
    console.log(xmlDoc);
  });

2.2 重要属性和方法

属性/方法说明示例
documentElement根元素xmlDoc.documentElement
getElementsByTagName()根据标签名获取节点列表xmlDoc.getElementsByTagName(“book”)
getElementById()如果 XML 有 id 属性(需 DTD)不常用
getAttribute()获取属性值node.getAttribute(“category”)
childNodes所有子节点(包括文本、注释)node.childNodes
firstChild / lastChild第一个/最后一个子节点node.firstChild
nextSibling / previousSibling兄弟节点node.nextSibling
nodeName节点名称“#text”、 “title”
nodeValue节点值(文本节点才有效)textNode.nodeValue
textContent获取元素内全部文本(推荐)element.textContent

2.3 读取示例

const books = xmlDoc.getElementsByTagName("book");

for (let i = 0; i < books.length; i++) {
  const book = books[i];
  const title = book.getElementsByTagName("title")[0].textContent;
  const author = book.getElementsByTagName("author")[0].textContent;
  const price = book.getElementsByTagName("price")[0].textContent;
  const lang = book.getElementsByTagName("title")[0].getAttribute("lang");

  console.log(`${title} (${lang}) - ${author},价格:${price}元`);
}

输出:

JavaScript 高级程序设计 (zh) - 扎卡斯,价格:99.00元
The Great Gatsby (en) - F. Scott Fitzgerald,价格:28.50元

2.4 修改节点

// 修改价格
books[0].getElementsByTagName("price")[0].textContent = "89.00";

// 修改属性
books[0].getElementsByTagName("title")[0].setAttribute("lang", "cn");

2.5 创建新节点

// 创建新书
const newBook = xmlDoc.createElement("book");
newBook.setAttribute("id", "3");
newBook.setAttribute("category", "科幻");

const title = xmlDoc.createElement("title");
title.setAttribute("lang", "zh");
title.textContent = "三体";

const author = xmlDoc.createElement("author");
author.textContent = "刘慈欣";

const year = xmlDoc.createElement("year");
year.textContent = "2008";

const price = xmlDoc.createElement("price");
price.textContent = "68.00";

newBook.appendChild(title);
newBook.appendChild(author);
newBook.appendChild(year);
newBook.appendChild(price);

// 添加到 bookstore
xmlDoc.documentElement.appendChild(newBook);

2.6 删除节点

// 删除第一本书
const firstBook = xmlDoc.getElementsByTagName("book")[0];
firstBook.parentNode.removeChild(firstBook);

2.7 把修改后的 XML 输出为字符串

const serializer = new XMLSerializer();
const newXmlString = serializer.serializeToString(xmlDoc);
console.log(newXmlString);

3. 其他语言快速示例

Python(xml.dom.minidom)

from xml.dom import minidom

# 读取文件
doc = minidom.parse("books.xml")

# 或从字符串
# doc = minidom.parseString(xml_string)

books = doc.getElementsByTagName("book")
for book in books:
    title = book.getElementsByTagName("title")[0].firstChild.data
    print(title)

# 创建新节点示例略,同 JS 思路

Java(javax.xml.parsers)

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("books.xml");

NodeList books = doc.getElementsByTagName("book");
// 遍历、修改类似

4. 常见面试题

  1. childNodes 和 children 的区别?
    childNodes 包含文本节点和注释节点,children 只包含元素节点。
  2. 如何获取某个元素的纯文本内容(推荐方式)?
    element.textContent 或 element.innerText(IE)
  3. 如何遍历所有属性?
   for (let attr of node.attributes) {
     console.log(attr.name + "=" + attr.value);
   }

5. 完整可运行 HTML 示例

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>XML DOM 演示</title>
</head>
<body>
  <button onclick="loadXML()">加载并显示图书</button>
  <pre id="output"></pre>

<script>
const xmlString = `<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="编程">
    <title lang="zh">JavaScript 权威指南</title>
    <author>弗拉纳根</author>
    <price>128.00</price>
  </book>
</bookstore>`;

function loadXML() {
  const parser = new DOMParser();
  const doc = parser.parseFromString(xmlString, "text/xml");

  const books = doc.getElementsByTagName("book");
  let result = "";
  for (let book of books) {
    const title = book.getElementsByTagName("title")[0];
    result += `${title.textContent} (${title.getAttribute("lang")})\n`;
  }
  document.getElementById("output").textContent = result;
}
</script>
</body>
</html>

这个教程涵盖了 95% 以上的实际开发场景。掌握了 JavaScript 的 DOM 操作,其他语言基本都是类似的思路。祝你玩得开心!如果需要更深入的 XPath、XML Schema、SAX 等高级内容,随时再问~

文章已创建 2732

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部