虽然现在JSON已经成为前后端数据交互的主流格式,但在对接一些老系统、政府接口、银行支付回调或者某些第三方SDK时,XML依然随处可见。前端拿到一段XML字符串,最直接的需求就是把它变成可以像DOM一样操作的节点对象,然后读取其中的文本和属性。JavaScript在浏览器端处理XML其实并不复杂,核心就是解析和遍历两步,下面详细介绍几种常用方法以及各自的注意点。

用DOMParser解析XML字符串
DOMParser是浏览器原生提供的解析器,可以把一段XML字符串直接解析成Document对象,这也是现代浏览器中最推荐的字符串解析方式。它不需要任何第三方库,解析完成后可以像操作普通HTML DOM一样使用getElementsByTagName、querySelector等方法提取数据。
基本用法非常简单,实例化一个parser对象后调用parseFromString方法,第二个参数传入"text/xml"即可:
const xmlStr = '<?xml version="1.0" encoding="UTF-8"?>' +
'<bookstore>' +
' <book category="web">' +
' <title>JavaScript高级程序设计</title>' +
' <price>99</price>' +
' </book>' +
' <book category="code">' +
' <title>代码整洁之道</title>' +
' <price>59</price>' +
' </book>' +
'</bookstore>';
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlStr, "text/xml");
// 用getElementsByTagName获取所有book节点
const books = xmlDoc.getElementsByTagName("book");
for (let i = 0; i < books.length; i++) {
const title = books[i].getElementsByTagName("title")[0].textContent;
const price = books[i].getElementsByTagName("price")[0].textContent;
const category = books[i].getAttribute("category");
console.log(title, price, category);
}需要特别注意的是解析失败的情况。如果XML格式有语法错误,DOMParser并不会抛出异常,而是返回一个包含parsererror节点的文档。所以在读取数据前最好先检查一下:
const xmlDoc = parser.parseFromString(xmlStr, "text/xml");
const err = xmlDoc.querySelector("parsererror");
if (err) {
console.error("XML解析出错:", err.textContent);
return;
}
// 正常处理逻辑这个坑很多人都踩过:明明XML字符串看起来没问题,结果取出来的数据全是undefined,一查才发现字符串里多了个未闭合的标签。养成先检查parsererror的习惯能省下不少排查时间。
通过XMLHttpRequest接收XML响应
如果XML数据来自服务端接口,最省事的方式是使用XMLHttpRequest的responseXML属性。只要服务端返回的Content-Type是text/xml或者application/xml,浏览器会自动完成解析,responseXML直接就是一个可用的Document对象,不需要再手动调用DOMParser。
const xhr = new XMLHttpRequest();
xhr.open("GET", "/api/data.xml", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
const xmlDoc = xhr.responseXML;
if (xmlDoc) {
const items = xmlDoc.getElementsByTagName("item");
console.log("共获取到 " + items.length + " 条数据");
} else {
// 响应头不是XML类型时,responseXML为null,需手动解析
const fallback = new DOMParser().parseFromString(xhr.responseText, "text/xml");
console.log(fallback);
}
}
};
xhr.send();这里有个常见的坑:如果服务端返回的Content-Type不对,比如返回了text/plain,那么responseXML会是null。此时可以用responseText拿到原始字符串,再交给DOMParser兜底处理。另外部分旧版浏览器需要显式调用xhr.overrideMimeType('text/xml')才能正确识别,建议在不确定服务端行为时加上这一句保险。
fetch并不直接提供responseXML属性,如果习惯用fetch,需要先调用res.text()拿到字符串再解析:
fetch("/api/data.xml")
.then(res => res.text())
.then(str => {
const xmlDoc = new DOMParser().parseFromString(str, "text/xml");
console.log(xmlDoc);
});遍历节点与读取属性的实用技巧
解析只是第一步,真正麻烦的是从层级复杂的XML中提取数据。除了getElementsByTagName,还可以使用childNodes和children做递归遍历。两者区别在于childNodes包含文本节点和注释节点,而children只包含元素节点,在统计子元素数量时用children更省心。
读取节点文本时统一使用textContent属性,它会返回节点下所有文本的拼接结果,比innerHTML更安全,也不会因为XML中不存在innerHTML语义而出问题。读取属性用getAttribute("属性名"),或者通过attributes集合遍历所有属性:
function walk(node, depth) {
if (node.nodeType !== 1) return; // 只处理元素节点
let indent = " ".repeat(depth);
console.log(indent + node.nodeName);
for (const attr of node.attributes) {
console.log(indent + " @" + attr.name + " = " + attr.value);
}
for (const child of node.children) {
walk(child, depth + 1);
}
}
walk(xmlDoc.documentElement, 0);如果要处理的XML带有命名空间,比如很多SOAP接口返回的报文,普通方法可能取不到节点。此时要使用带命名空间参数的方法,例如getElementsByTagNameNS,或者直接用带前缀写法的querySelector。遇到取不到节点的情况,先打印一下xmlDoc.documentElement.namespaceURI确认命名空间,再选择对应的查询方式。
兼容旧环境与方案选择建议
在极老的项目里可能还会见到ActiveX方式的解析代码,即通过new ActiveXObject("Microsoft.XMLDOM")加载XML。这种方式只在旧版IE中可用,现代浏览器包括Edge都已不再支持,除非明确要兼容IE8及以下环境,否则不建议再写这种代码。新项目统一使用DOMParser和responseXML即可,所有主流浏览器的支持都非常完善。
选型上可以按数据来源区分:字符串来源就用DOMParser,接口响应优先用XMLHttpRequest的responseXML,fetch用户则手动text加parse组合。如果XML结构非常庞大且需要频繁查询,还可以考虑把解析后的数据转换成普通的JavaScript对象数组再操作,遍历性能和代码可读性都会更好。总之,浏览器原生能力已经足够应对绝大多数XML处理场景,不必为了一个简单的解析需求引入额外的库。
JavaScript解析XMLDOMParserXMLHttpRequest修改时间:2026-09-09 15:03:04