如何用JavaScript遍历XML节点树

JavaScript遍历XML节点树需先用DOMParser(或IE的ActiveXObject)解析字符串为DOM文档,再按nodeType区分元素、属性、文本节点递归访问,注意过滤空白文本并兼顾浏览器兼容性。

JavaScript遍历XML节点树,核心是把XML字符串解析成DOM文档对象,再用标准DOM方法逐层访问节点。关键在于正确解析、区分节点类型、处理文本内容,并注意浏览器兼容性(尤其是旧版IE)。

解析XML字符串为DOM文档

现代浏览器支持 DOMParser,是最通用的方式:

const xmlStr = `
  
    Harry Potter
    J.K. Rowling
  
`;

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

// 检查是否解析失败(如语法错误)
if (xmlDoc.querySelector("parsererror")) {
  console.error("XML解析失败");
}

递归遍历所有节点(含元素、属性、文本)

XML节点类型多样(元素、属性、文本、注释等),需用 nodeType 判断,避免误读空白文本节点:

  • 1 元素节点(nodeType === 1):可获取标签名、属性、子节点
  • 2 属性节点(nodeType === 2):在元素的 attributes 集合中,不自动出现在 childNodes
  • 3 文本节点(nodeType === 3):注意过滤掉纯空白(如换行缩进)

示例递归函数:

function traverse(node, depth = 0) {
  const indent = "  ".repeat(depth);
  
  switch(node.nodeType) {
    case 1: // 元素节点
      console.log(`${indent}<${node.nodeName}>`);
      // 遍历属性
      for (let attr of node.attributes || []) {
        console.log(`${indent}  @${attr.name}="${attr.value}"`);
      }
      // 遍历子节点
      for (let child of node.childNodes) {
        traverse(child, depth + 1);
      }
      break;
    case 3: // 文本节点,只打印非空白内容
      const text = node.nodeValue.trim();
      if (text) {
        console.log(`${indent}#text: "${text}"`);
      }
      break;
  }
}

traverse(xmlDoc.documentElement); // 从根元素开始

按需遍历:常用快捷方式

实际开发中很少全量递归,更多是定位目标节点:

  • 获取所有同名元素xmlDoc.getElementsByTagName("title")
  • 查找带特定属性的元素xmlDoc.querySelectorAll('book[category="fiction"]')
  • 获取某个元素的文本内容element.textContent(推荐)或 element.firstChild.nodeValue
  • 读取属性值element.getAttribute("lang")element.getAttributeNode("lang").value

兼容IE8–9的备用方案(已过时但偶有需要)

老版IE不支持 DOMParser,需用 ActiveXObject

function parseXMLForIE(xmlStr) {
  if (window.ActiveXObject) {
    const doc = new ActiveXObject("Microsoft.XMLDOM");
    doc.async = false;
    doc.loadXML(xmlStr);
    return doc;
  }
  // 其他浏览器走 DOMParser
}

不复杂但容易忽略细节。重点是先确保解析成功,再按节点类型安全访问,避免直接调用 nodeValue 在非文本节点上。