XML DOM 完整实战实例合集(2025 年真实生产级代码)
以下 8 个实例覆盖了前端开发中 99% 的 XML 场景,直接复制可用,带详细注释。
1. 安全解析任意 XML(必备第一步)
function parseXML(xmlString) {
const doc = new DOMParser().parseFromString(xmlString, "text/xml");
// 关键:所有浏览器解析错误都不抛异常!
const error = doc.querySelector("parsererror");
if (error) {
const msg = error.querySelector("p")?.textContent || "XML 语法错误";
throw new Error(`XML 解析失败:${msg}`);
}
return doc;
}
2. 读取并提取 RSS/Atom 新闻
<!-- rss.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>前端日报</title>
<item>
<title>XML 仍然重要</title>
<link>https://example.com/1</link>
<description><![CDATA[<p>XML DOM 详解...</p>]]></description>
<pubDate>Wed, 26 Nov 2025 10:00:00 GMT</pubDate>
</item>
</channel>
</rss>
async function loadRSS() {
const resp = await fetch("rss.xml");
const text = await resp.text();
const doc = parseXML(text);
const items = doc.querySelectorAll("item");
return Array.from(items).map(item => ({
title: item.querySelector("title")?.textContent,
link: item.querySelector("link")?.textContent,
desc: item.querySelector("description")?.textContent, // 自动保留 CDATA 内 HTML
date: new Date(item.querySelector("pubDate")?.textContent)
}));
}
3. 动态生成带命名空间的 SVG
function createSVG() {
const SVG_NS = "http://www.w3.org/2000/svg";
const doc = document.implementation.createDocument(SVG_NS, "svg", null);
const svg = doc.documentElement;
svg.setAttribute("width", "400");
svg.setAttribute("height", "200");
svg.setAttribute("viewBox", "0 0 400 200");
const circle = doc.createElementNS(SVG_NS, "circle");
circle.setAttribute("cx", "200");
circle.setAttribute("cy", "100");
circle.setAttribute("r", "80");
circle.setAttribute("fill", "red");
const text = doc.createElementNS(SVG_NS, "text");
text.setAttribute("x", "200");
text.setAttribute("y", "115");
text.setAttribute("text-anchor", "middle");
text.setAttribute("fill", "white");
text.textContent = "XML DOM";
svg.appendChild(circle);
svg.appendChild(text);
// 输出或插入页面
document.body.innerHTML = new XMLSerializer().serializeToString(doc);
}
4. 生成带 的完整 XML 文件并下载
function downloadXML() {
const xmlDoc = document.implementation.createDocument("", "root", null);
const pi = xmlDoc.createProcessingInstruction(
"xml-stylesheet",
'type="text/xsl" href="style.xsl"'
);
xmlDoc.insertBefore(pi, xmlDoc.firstChild);
const comment = xmlDoc.createComment("Generated by MyApp v1.0");
xmlDoc.insertBefore(comment, xmlDoc.documentElement);
const root = xmlDoc.documentElement;
root.setAttribute("created", new Date().toISOString());
const user = xmlDoc.createElement("user");
user.setAttribute("id", "1");
user.appendChild(xmlDoc.createElement("name")).textContent = "张三";
user.appendChild(xmlDoc.createElement("age")).textContent = "30";
root.appendChild(user);
const xmlString = new XMLSerializer().serializeToString(xmlDoc);
const blob = new Blob(["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + xmlString], {
type: "application/xml"
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "data.xml";
a.click();
}
5. 读取并修改 Office Open XML(docx 中的 word/document.xml)
async function editDocx() {
const resp = await fetch("template.docx");
const arrayBuffer = await resp.arrayBuffer();
const zip = await JSZip.loadAsync(arrayBuffer);
let xmlStr = await zip.file("word/document.xml").async("text");
const doc = parseXML(xmlStr);
// 替换占位符
doc.querySelectorAll("w|t").forEach(t => {
if (t.textContent.includes("{{name}}")) {
t.textContent = t.textContent.replace("{{name}}", "李四");
}
});
const newXml = new XMLSerializer().serializeToString(doc);
zip.file("word/document.xml", newXml);
const newBlob = await zip.generateAsync({ type: "blob" });
download(newBlob, "edited.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
}
6. 克隆带命名空间和属性的节点(最容易出错的点)
function deepCloneWithNS(sourceElement, targetDoc) {
// 正确方式:必须带命名空间克隆
const clone = targetDoc.createElementNS(
sourceElement.namespaceURI,
sourceElement.tagName
);
// 复制所有属性(包括 xmlns、xsi:schemaLocation)
for (const attr of sourceElement.attributes) {
if (attr.namespaceURI) {
clone.setAttributeNS(attr.namespaceURI, attr.name, attr.value);
} else {
clone.setAttribute(attr.name, attr.value);
}
}
// 递归子节点
for (const child of sourceElement.childNodes) {
if (child.nodeType === 1) { // Element
clone.appendChild(deepCloneWithNS(child, targetDoc));
} else if (child.nodeType === 3 || child.nodeType === 4 || child.nodeType === 8) {
clone.appendChild(targetDoc.importNode(child, true));
}
}
return clone;
}
7. 批量导入 XML 数据到页面(性能优化版)
function renderBooks(xmlString) {
const doc = parseXML(xmlString);
const frag = document.createDocumentFragment();
doc.querySelectorAll("book").forEach(book => {
const div = document.createElement("div");
div.innerHTML = `
<h3>${book.querySelector("title")?.textContent}</h3>
<p>价格:${book.querySelector("price")?.textContent}</p>
`;
frag.appendChild(div);
});
document.getElementById("list").innerHTML = "";
document.getElementById("list").appendChild(frag);
}
8. 最强通用工具函数(复制到项目里直接用)
const XML = {
parse: (str) => {
const doc = new DOMParser().parseFromString(str, "text/xml");
if (doc.querySelector("parsererror")) throw new Error("Invalid XML");
return doc;
},
serialize: (doc) => new XMLSerializer().serializeToString(doc),
create: (rootName, ns = null) => {
return ns
? document.implementation.createDocument(ns, rootName, null)
: document.implementation.createDocument("", rootName, null);
},
download: (doc, filename = "data.xml") => {
const data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + XML.serialize(doc);
const blob = new Blob([data], { type: "application/xml" });
const url = URL.createObjectURL(blob);
const a = Object.assign(document.createElement("a"), { href: url, download: filename });
a.click();
}
};
总结:8 个实例覆盖全部场景
| 场景 | 对应实例 |
|---|---|
| 读取 RSS/Atom | 2 |
| 生成 SVG | 3 |
| 导出完整 XML 文件 | 4 |
| 修改 docx/pptx | 5 |
| 克隆复杂命名空间节点 | 6 |
| 大量数据渲染 | 7 |
| 生产环境安全解析 | 1 + 8 |
把这 8 个例子吃透,恭喜你:你已经完全掌握了现代前端中所有的 XML DOM 实战技能!