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. 常见面试题
- childNodes 和 children 的区别?
childNodes 包含文本节点和注释节点,children 只包含元素节点。 - 如何获取某个元素的纯文本内容(推荐方式)?
element.textContent 或 element.innerText(IE) - 如何遍历所有属性?
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 等高级内容,随时再问~