XML DOM – Node 对象(长文解析)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

前言:为什么 Node 对象是 XML 开发的关键?

在处理 XML 文档时,DOM(文档对象模型)提供了一种结构化的方式,将 XML 文件解析为树状对象。而 Node 对象作为 DOM 的核心组成部分,是操作 XML 数据的基础单元。无论是读取节点内容、修改节点属性,还是遍历整个文档结构,Node 对象都扮演着不可或缺的角色。对于编程初学者和中级开发者而言,掌握 Node 对象的操作逻辑,能够显著提升 XML 数据处理的效率和准确性。

本文将通过循序渐进的方式,结合具体案例和代码示例,帮助读者理解 Node 对象的属性、方法及实际应用场景。


一、XML DOM 的基础概念:从文档到节点

1.1 XML DOM 的层级结构

XML 文档可以被视为一棵树,每个元素、属性或文本内容都是树中的一个节点(Node)。例如,以下 XML 片段:

<books>  
  <book id="1">  
    <title>JavaScript 核心编程</title>  
    <author>John Doe</author>  
  </book>  
</books>  

对应的 DOM 树结构如下:

  • 根节点<books>
  • 子节点<book>(元素节点)、文本节点(如换行空格)
  • 后代节点<title><author> 元素及文本内容

1.2 Node 对象的核心属性

每个 Node 对象都有以下关键属性,用于描述其在文档中的角色和位置:

属性名描述
nodeType表示节点类型(如元素节点、文本节点等),返回数值类型。
nodeName返回节点名称(如元素的标签名或属性名)。
nodeValue存储节点的文本值,仅对文本节点有效。
parentNode指向当前节点的父节点。
childNodes返回一个包含所有子节点的集合(NodeList 类型)。
firstChild获取第一个子节点。
lastChild获取最后一个子节点。
nextSibling获取同级节点中的下一个节点。
previousSibling获取同级节点中的上一个节点。

形象比喻
可以将 Node 对象想象为一棵树上的树枝,每个树枝(节点)都有自己的名称(nodeName)、位置(父节点、子节点)和内容(nodeValue)。通过这些属性,我们可以像“导航树杈”一样定位到任意节点。


二、Node 对象的核心方法:操作与遍历

2.1 常用操作方法

Node 对象提供了多种方法,用于增删改查节点:

2.1.1 appendChild()removeChild()

作用:向父节点添加或移除子节点。

示例代码(JavaScript)

// 创建新节点  
const newBook = document.createElement("book");  
const newTitle = document.createTextNode("新书标题");  

// 将 newTitle 添加为 newBook 的子节点  
newBook.appendChild(newTitle);  

// 移除某个子节点  
const parent = document.querySelector("books");  
parent.removeChild(parent.firstChild);  

2.1.2 cloneNode()

作用:复制节点及其子节点(需指定 deep 参数为 true)。

const clonedNode = originalNode.cloneNode(true); // 深拷贝  

2.2 节点遍历的技巧

遍历 XML 树结构是操作 Node 对象的常见需求。以下是两种常用方法:

2.2.1 递归遍历法

通过递归函数遍历所有子节点:

function traverseNodes(node) {  
  if (node.nodeType === Node.ELEMENT_NODE) {  
    console.log("元素节点:", node.nodeName);  
  } else if (node.nodeType === Node.TEXT_NODE) {  
    console.log("文本内容:", node.nodeValue.trim());  
  }  

  // 遍历子节点  
  const children = node.childNodes;  
  for (let i = 0; i < children.length; i++) {  
    traverseNodes(children[i]);  
  }  
}  

2.2.2 使用 querySelectorquerySelectorAll

通过 CSS 选择器快速定位特定节点:

// 获取所有 <title> 元素  
const titles = document.querySelectorAll("title");  

// 修改第一个 <title> 的文本内容  
titles[0].firstChild.nodeValue = "修改后的书名";  

三、Node 对象的高级用法:属性与命名空间

3.1 处理节点属性

XML 元素的属性(如 id="1")也以 Node 对象的形式存在。通过 attributes 属性或 getAttribute() 方法可以操作它们:

// 获取元素的 id 属性  
const bookElement = document.querySelector("book");  
const idAttr = bookElement.getAttribute("id"); // 返回 "1"  

// 添加新属性  
bookElement.setAttribute("category", "编程");  

3.2 命名空间(Namespaces)的处理

在复杂 XML 文档中,命名空间用于区分不同来源的标签。例如:

<mathml:math xmlns:mathml="http://www.w3.org/1998/Math/MathML">  
  <mathml:mi>x</mathml:mi>  
</mathml:math>  

此时,需通过 namespaceURI 属性和 lookupPrefix() 方法操作命名空间:

const mathNode = document.querySelector("mathml\\:math"); // 注意转义冒号  
const prefix = mathNode.lookupPrefix(mathNode.namespaceURI); // 返回 "mathml"  

四、实战案例:构建 XML 数据处理器

4.1 案例目标

创建一个工具类,实现以下功能:

  1. 从字符串解析 XML;
  2. 查询特定节点并修改其内容;
  3. 生成新的 XML 字符串。

4.2 实现代码(JavaScript)

class XMLProcessor {  
  constructor(xmlString) {  
    // 解析 XML 字符串为 DOM  
    const parser = new DOMParser();  
    this.doc = parser.parseFromString(xmlString, "application/xml");  
    this.root = this.doc.documentElement; // 获取根节点  
  }  

  // 修改指定路径的文本内容  
  updateText(xpath, newText) {  
    const targetNode = this.doc.evaluate(  
      xpath,  
      this.root,  
      null,  
      XPathResult.FIRST_ORDERED_NODE_TYPE,  
      null  
    ).singleNodeValue;  

    if (targetNode && targetNode.firstChild) {  
      targetNode.firstChild.nodeValue = newText;  
    }  
  }  

  // 生成 XML 字符串  
  toString() {  
    const serializer = new XMLSerializer();  
    return serializer.serializeToString(this.doc);  
  }  
}  

// 使用示例  
const xmlStr = `  
<books>  
  <book id="1">  
    <title>旧书名</title>  
  </book>  
</books>`;  

const processor = new XMLProcessor(xmlStr);  
processor.updateText("//book/title", "新书名");  
console.log(processor.toString());  

4.3 输出结果

<?xml version="1.0" encoding="UTF-8"?>  
<books>  
  <book id="1">  
    <title>新书名</title>  
  </book>  
</books>  

结论:Node 对象是 XML 开发的基石

通过本文的学习,读者可以掌握 Node 对象的核心属性、方法以及实际应用场景。无论是简单的节点查询,还是复杂的 XML 文档操作,Node 对象都提供了灵活且高效的方式。建议读者通过以下步骤巩固知识:

  1. 使用在线 XML 编辑器(如 XML Playground )实践代码示例;
  2. 尝试将 XML 数据与前端框架(如 React/Vue)结合,实现动态渲染;
  3. 探索 Node 对象在服务器端处理 XML 文件的场景(如 Node.js 的 xmldom 库)。

掌握 Node 对象不仅是理解 XML DOM 的关键,更是构建数据驱动应用的重要基础。希望本文能为您的 XML 开发之路提供清晰的指引!

最新发布