写点什么

DOM(文档对象模型):理解网页结构与内容操作的关键技术

作者:小万哥
  • 2024-03-29
    广东
  • 本文字数:4849 字

    阅读完需:约 16 分钟

DOM(文档对象模型):理解网页结构与内容操作的关键技术

DOM(文档对象模型)定义了一种访问和操作文档的标准。它是一个平台和语言无关的接口,允许程序和脚本动态访问和更新文档的内容、结构和样式。HTML DOM 用于操作 HTML 文档,而 XML DOM 用于操作 XML 文档。


HTML DOM 示例

通过 ID 获取并修改 HTML 元素的值:

<!DOCTYPE html><html><head><style>table, th, td {  border: 1px solid black;  border-collapse: collapse;}th, td {  padding: 5px;}</style></head><body>
<button type="button" onclick="loadXMLDoc()">获取我的CD收藏</button><br><br><table id="demo"></table>
<script>function loadXMLDoc() { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { myFunction(this); } }; xmlhttp.open("GET", "cd_catalog.xml", true); xmlhttp.send();}
function myFunction(xml) { var i; var xmlDoc = xml.responseXML; var table = "<tr><th>Artist</th><th>Title</th></tr>"; var x = xmlDoc.getElementsByTagName("CD"); for (i = 0; i < x.length; i++) { table += "<tr><td>" + x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue + "</td><td>" + x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + "</td></tr>"; } document.getElementById("demo").innerHTML = table;}</script>
</body></html>
复制代码

通过标签名获取并修改 HTML 元素的值:

<!DOCTYPE html><html><body>
<h1>This is a Heading</h1>
<h1>This is another Heading</h1>
<script>document.getElementsByTagName("h1")[0].innerHTML = "Hello World!";</script>
</body></html>
复制代码


XML DOM 示例

加载 XML 文件并获取元素的值:

<!DOCTYPE html><html><body>
<p id="demo"></p>
<script>var xhttp = new XMLHttpRequest();xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { myFunction(this); }};xhttp.open("GET", "books.xml", true);xhttp.send();
function myFunction(xml) { var xmlDoc = xml.responseXML; document.getElementById("demo").innerHTML = xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;}</script>
</body></html>
复制代码

加载 XML 字符串并获取元素的值:

<html><body>
<p id="demo"></p>
<script>var text, parser, xmlDoc;
text = "<bookstore><book>" +"<title>Everyday Italian</title>" +"<author>Giada De Laurentiis</author>" +"<year>2005</year>" +"</book></bookstore>";
parser = new DOMParser();xmlDoc = parser.parseFromString(text,"text/xml");
document.getElementById("demo").innerHTML =xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue;</script>
</body></html>
复制代码

DOM 编程接口

DOM 的编程接口由一组标准属性和方法定义。属性通常用于描述节点的特征,而方法通常用于执行与节点相关的操作。


属性的例子


  • x.nodeName - x 的名称

  • x.nodeValue - x 的值

  • x.parentNode - x 的父节点

  • x.childNodes - x 的子节点

  • x.attributes - x 的属性节点


方法的例子


  • x.getElementsByTagName(name) - 获取指定标签名的所有元素

  • x.appendChild(node) - 将一个子节点插入到 x

  • x.removeChild(node) - 从 x 中移除一个子节点


这些属性和方法使得通过编程可以访问和操作文档的各个部分。

XML DOM 节点

根据 XML DOM,XML 文档中的所有内容都是节点:


  • 整个文档是一个文档节点

  • 每个 XML 元素是一个元素节点

  • XML 元素中的文本是文本节点

  • 每个属性是一个属性节点

  • 注释是注释节点


DOM 示例


看下面的 XML 文件(books.xml):


<?xml version="1.0" encoding="UTF-8"?><bookstore>  <book category="cooking">    <title lang="en">Everyday Italian</title>    <author>Giada De Laurentiis</author>    <year>2005</year>    <price>30.00</price>  </book>  <book category="children">    <title lang="en">Harry Potter</title>    <author>J.K. Rowling</author>    <year>2005</year>    <price>29.99</price>  </book>  <book category="web">    <title lang="en">XQuery Kick Start</title>    <author>James McGovern</author>    <author>Per Bothner</author>    <author>Kurt Cagle</author>    <author>James Linn</author>    <author>Vaidyanathan Nagarajan</author>    <year>2003</year>    <price>49.99</price>  </book>  <book category="web" cover="paperback">    <title lang="en">Learning XML</title>    <author>Erik T. Ray</author>    <year>2003</year>    <price>39.95</price>  </book></bookstore>
复制代码


上述 XML 中的根节点命名为 <bookstore>


文档中的所有其他节点都包含在 <bookstore> 中。


根节点 <bookstore> 包含了 4 个 <book> 节点。


第一个 <book> 节点包含子节点: <title><author><year><price>


子节点分别包含一个文本节点,内容分别为 "Everyday Italian"、"Giada De Laurentiis"、"2005" 和 "30.00"。

文本始终存储在文本节点中

在 DOM 处理中常见的错误是期望元素节点包含文本。然而,元素节点的文本存储在文本节点中。


在这个例子中:<year>2005</year>,元素节点 <year> 包含一个值为 "2005" 的文本节点。


"2005" 不是 <year> 元素的值!

XML DOM 节点树

XML DOM 将 XML 文档视为树结构。树结构被称为节点树。


所有节点都可以通过树访问。它们的内容可以修改或删除,并且可以创建新元素。


节点树显示了节点集和它们之间的连接。树从根节点开始,延伸到树的最低层的文本节点:



图像上方代表 XML 文件 books.xml

节点的父节点、子节点和兄弟姐妹

节点树中的节点之间存在层次关系。


术语父节点、子节点和兄弟姐妹用于描述这些关系。父节点有子节点。在同一层级上的子节点称为兄弟姐妹。


  • 在节点树中,顶部节点称为根节点

  • 除了根节点,每个节点都有一个父节点

  • 一个节点可以有任意数量的子节点

  • 叶子是没有子节点的节点

  • 具有相同父节点的节点称为兄弟节点


以下图像说明了节点树的一部分以及节点之间的关系:



由于 XML 数据是以树形式结构化的,可以在不知道树的确切结构和包含的数据类型的情况下遍历它。

第一个子节点 - 最后一个子节点

看下面的 XML 片段:


<bookstore>  <book category="cooking">    <title lang="en">Everyday Italian</title>    <author>Giada De Laurentiis</author>    <year>2005</year>    <price>30.00</price>  </book></bookstore>
复制代码


在上述 XML 中,<title> 元素是 <book> 元素的第一个子节点,<price> 元素是 <book> 元素的最后一个子节点。


此外,<book> 元素是 <title><author><year><price> 元素的父节点。

XML DOM - 访问节点

使用 DOM,您可以访问 XML 文档中的每个节点。

访问节点

有三种方式可以访问节点:


  1. 使用 getElementsByTagName() 方法

  2. 通过循环遍历节点树

  3. 通过导航节点树,使用节点之间的关系

getElementsByTagName() 方法

getElementsByTagName() 返回具有指定标签名的所有元素。


语法


node.getElementsByTagName("tagname");
复制代码


示例


以下示例返回 x 元素下的所有 <title> 元素:


x.getElementsByTagName("title");
复制代码


注意,上面的示例仅返回 x 节点下的 <title> 元素。要返回 XML 文档中的所有 <title> 元素,请使用:


xmlDoc.getElementsByTagName("title");
复制代码


其中 xmlDoc 是文档本身(文档节点)。

DOM 节点列表

getElementsByTagName() 方法返回一个节点列表。节点列表是节点的数组。


x = xmlDoc.getElementsByTagName("title");
复制代码


x 中的 <title> 元素可以通过索引号访问。要访问第三个 <title>,您可以这样写:


y = x[2];
复制代码


注意:索引从 0 开始。

DOM 节点列表长度

length 属性定义了节点列表的长度(节点数)。


您可以通过使用 length 属性循环遍历节点列表:


var x = xmlDoc.getElementsByTagName("title");
for (i = 0; i < x.length; i++) { // 对每个节点执行一些操作}
复制代码

节点类型

XML 文档的 documentElement 属性是根节点。


节点的 nodeName 属性是节点的名称。


节点的 nodeType 属性是节点的类型

遍历节点

以下代码循环遍历根节点的子节点,这些子节点也是元素节点:


txt = "";x = xmlDoc.documentElement.childNodes;
for (i = 0; i < x.length; i++) { // 仅处理元素节点(类型 1) if (x[i].nodeType == 1) { txt += x[i].nodeName + "<br>"; }}
复制代码


示例解释:


  • 假设您已经将 "books.xml" 加载到 xmlDoc

  • 获取根元素(xmlDoc)的子节点

  • 对于每个子节点,检查节点类型。如果节点类型是 "1",则它是一个元素节点

  • 如果它是一个元素节点,则输出节点的名称

导航节点关系

以下代码使用节点之间的关系导航节点树:


x = xmlDoc.getElementsByTagName("book")[0];xlen = x.childNodes.length;y = x.firstChild;
txt = "";for (i = 0; i < xlen; i++) { // 仅处理元素节点(类型 1) if (y.nodeType == 1) { txt += y.nodeName + "<br>"; } y = y.nextSibling;}
复制代码


示例解释:


  • 假设您已经将 "books.xml" 加载到 xmlDoc

  • 获取第一个 book 元素的子节点

  • 将 "y" 变量设置为第一个 book 元素的第一个子节点

  • 对于每个子节点(从第一个子节点 "y" 开始):

  • 检查节点类型。如果节点类型是 "1",则它是一个元素节点

  • 如果它是一个元素节点,则输出节点的名称

  • 将 "y" 变量设置为下一个兄弟节点,并再次运行循环

XML DOM 节点信息

nodeName 属性

nodeName 属性指定节点的名称。


  • nodeName 是只读的。

  • 元素节点的 nodeName 与标签名相同。

  • 属性节点的 nodeName 是属性名。

  • 文本节点的 nodeName 始终是 #text。

  • 文档节点的 nodeName 始终是 #document。


nodeName 属性示例

nodeValue 属性

nodeValue 属性指定节点的值。


  • 元素节点的 nodeValue 是未定义的。

  • 文本节点的 nodeValue 是文本本身。

  • 属性节点的 nodeValue 是属性值。

获取元素的值

以下代码检索第一个 <title> 元素的文本节点值:


var x = xmlDoc.getElementsByTagName("title")[0].childNodes[0];var txt = x.nodeValue;
复制代码


结果:txt = "Everyday Italian"


示例解释:


  • 假设您已经将 books.xml 加载到 xmlDoc 中。

  • 获取第一个 <title> 元素节点的文本节点。

  • txt 变量设置为文本节点的值。

更改元素的值

以下代码更改了第一个 <title> 元素的文本节点值:


var x = xmlDoc.getElementsByTagName("title")[0].childNodes[0];x.nodeValue = "Easy Cooking";
复制代码


示例解释:


  • 假设您已经将 books.xml 加载到 xmlDoc 中。

  • 获取第一个 <title> 元素节点的文本节点。

  • 将文本节点的值更改为 "Easy Cooking"。

nodeType 属性

nodeType 属性指定节点的类型。


  • nodeType 是只读的。

  • 最重要的节点类型是:

  • 元素:1

  • 属性:2

  • 文本:3

  • 注释:8

  • 文档:9


nodeType 属性示例

DOM 属性列表(命名节点映射)

元素节点的 attributes 属性返回属性节点的列表。


这称为命名节点映射,与节点列表类似,只是在方法和属性上有一些差异。


属性列表会自我更新。如果删除或添加了属性,列表会自动更新。


此代码片段从 "books.xml" 中的第一个 <book> 元素返回属性节点的列表:


x = xmlDoc.getElementsByTagName('book')[0].attributes;
复制代码


执行上述代码后,x.length 是属性的数量,x.getNamedItem() 可用于返回一个属性节点。


此代码片段获取书籍的 "category" 属性值和属性列表的数量:


x = xmlDoc.getElementsByTagName("book")[0].attributes;
txt = x.getNamedItem("category").nodeValue + " " + x.length;
复制代码


输出:


  • cooking 1


示例解释:


  • 假设 books.xml 已加载到 xmlDoc 中。

  • 设置 x 变量以保存第一个 <book> 元素的所有属性的列表。

  • 获取 "category" 属性的值和属性列表的长度。

最后

为了方便其他设备和平台的小伙伴观看往期文章:


微信公众号搜索:Let us Coding,关注后即可获取最新文章推送


看完如果觉得有帮助,欢迎点赞、收藏、关注

发布于: 刚刚阅读数: 4
用户头像

小万哥

关注

代码如人生 2023-02-09 加入

编程爱好者

评论

发布
暂无评论
DOM(文档对象模型):理解网页结构与内容操作的关键技术_xml_小万哥_InfoQ写作社区