XML DOM 节点树

XML DOM 节点树(图文最清楚版)

XML DOM 的核心思想就是:把整个 XML 文档在内存中表示成一棵“节点树”(Node Tree)
你可以像逛公园一样在这棵树上随意“走来走去、修枝剪叶”。

1. 节点树完整结构图(强烈建议看这个图)

拿下面这个 XML 为例:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE bookstore SYSTEM "bookstore.dtd">
<bookstore specialty="IT技术">
  <!-- 热门图书区 -->
  <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="zh">三体</title>
    <author>刘慈欣</author>
  </book>
</bookstore>

这棵完整的节点树长这样(竖向展开):

文档节点 (Document)                     nodeType=9   #document
│
├── 处理指令节点 (xml声明)              nodeType=7   target="xml"
├── 文档类型节点 (DOCTYPE)              nodeType=10  bookstore
├── 注释节点 (<!-- 热门图书区 -->)      nodeType=8
│
└── 元素节点 <bookstore>                nodeType=1   bookstore
    ├── 属性节点 specialty="IT技术"
    ├── 属性节点 (没有 id)
    │
    ├── 文本节点(换行+空格)           nodeType=3   "#text"
    ├── 注释节点(<!-- 热门图书区 -->)
    ├── 文本节点(换行+空格)
    │
    └── 元素节点 <book> (第一本)         nodeType=1   book
        ├── 属性节点 id="1"
        ├── 属性节点 category="编程"
        │
        ├── 文本节点(换行+缩进)
        │
        ├── 元素节点 <title>             nodeType=1   title
        │   ├── 属性节点 lang="zh"
        │   └── 文本节点 "JavaScript 高级程序设计"
        │
        ├── 文本节点(换行+缩进)
        ├── 元素节点 <author>            "扎卡斯"
        ├── 文本节点(换行+缩进)
        ├── 元素节点 <year>              "2020"
        ├── 文本节点(换行+缩进)
        └── 元素节点 <price>             "99.00"
        │
        ├── 文本节点(换行)
        │
        └── 元素节点 <book> (第二本)     nodeType=1   book
            ├── 属性节点 id="2"
            ├── 属性节点 category="科幻"
            ├── 文本节点(换行+缩进)
            ├── 元素节点 <title lang="zh"> "三体"
            └── 元素节点 <author>        "刘慈欣"

2. 节点树中的“家族关系”口诀(背会就无敌)

关系属性名说明例子
爸爸parentNode永远只有一个(文档节点除外)book.parentNode → bookstore
儿子们childNodes包含所有子节点(包括文本、注释)bookstore.childNodes
只认亲儿子children只包含元素子节点(不含文本、注释)bookstore.children
大儿子firstChild可能是空白文本!bookstore.firstChild → 换行文本
小儿子lastChild同上
大哥previousSibling上一个兄弟(可能也是文本)第二个book.previousSibling → 换行
弟弟nextSibling下一个兄弟
第一个亲儿子firstElementChild跳过空白文本,直接拿到第一个元素子节点bookstore.firstElementChild → book
最后一个亲儿子lastElementChild同上

现代浏览器推荐使用下面这四个(自动跳过空白文本):

parent.firstElementChild
parent.lastElementChild
node.previousElementSibling
node.nextElementSibling

3. 实战遍历整棵树(三种经典写法)

const doc = new DOMParser().parseFromString(xmlStr, "text/xml");
const root = doc.documentElement; // <bookstore>

// 写法1:递归遍历(最常用)
function walk(node, depth = 0) {
  const indent = "  ".repeat(depth);
  console.log(indent + node.nodeName + 
              (node.nodeType === 3 ? `="${node.nodeValue.trim()}"` : "") +
              (node.nodeType === 1 ? ` [${node.nodeType}]` : ""));

  for (let child of node.childNodes) {
    walk(child, depth + 1);
  }
}
walk(doc);
// 写法2:只遍历元素节点(推荐日常使用)
function walkElements(node) {
  console.log(node.tagName);
  for (let child of node.children) {
    walkElements(child);
  }
}
walkElements(root);
// 写法3:用 nextElementSibling 横向遍历所有 book
let book = root.firstElementChild;
while (book) {
  console.log(book.getAttribute("id"), book.querySelector("title").textContent);
  book = book.nextElementSibling;
}

4. 一句话总结

XML DOM 节点树 = 整个 XML 文档在内存里长成的一棵“家族树”

  • 文档节点是“老祖宗”
  • 元素是“人”
  • 属性是“人身上的标签”
  • 文本是“人说的话”
  • 换行和空格也是“人”(空白文本节点),你得学会无视他们

记住这棵树 + 上面那张“家族关系表”,你就已经掌握了 XML DOM 70% 的精髓!

需要我画一个彩色的思维导图或给你一个可交互的 HTML 节点树演示页面,随时说一声~

文章已创建 2732

发表回复

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

相关文章

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

返回顶部