DOM(文档对象模型)定义了一种访问和操作文档的标准。它是一个平台和语言无关的接口,允许程序和脚本动态访问和更新文档的内容、结构和样式。HTML DOM用于操作HTML文档,而XML DOM用于操作XML文档。
HTML DOM示例
通过ID获取并修改HTML元素的值:
1<!DOCTYPE html> 2<html> 3<head> 4<style> 5table, th, td { 6 border: 1px solid black; 7 border-collapse: collapse; 8} 9th, td { 10 padding: 5px; 11} 12</style> 13</head> 14<body> 15 16<button type="button" onclick="loadXMLDoc()">获取我的CD收藏</button> 17<br><br> 18<table id="demo"></table> 19 20<script> 21function loadXMLDoc() { 22 var xmlhttp = new XMLHttpRequest(); 23 xmlhttp.onreadystatechange = function() { 24 if (this.readyState == 4 && this.status == 200) { 25 myFunction(this); 26 } 27 }; 28 xmlhttp.open("GET", "cd_catalog.xml", true); 29 xmlhttp.send(); 30} 31 32function myFunction(xml) { 33 var i; 34 var xmlDoc = xml.responseXML; 35 var table = "<tr><th>Artist</th><th>Title</th></tr>"; 36 var x = xmlDoc.getElementsByTagName("CD"); 37 for (i = 0; i < x.length; i++) { 38 table += "<tr><td>" + 39 x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue + 40 "</td><td>" + 41 x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue + 42 "</td></tr>"; 43 } 44 document.getElementById("demo").innerHTML = table; 45} 46</script> 47 48</body> 49</html>
通过标签名获取并修改HTML元素的值:
1<!DOCTYPE html> 2<html> 3<body> 4 5<h1>This is a Heading</h1> 6 7<h1>This is another Heading</h1> 8 9<script> 10document.getElementsByTagName("h1")[0].innerHTML = "Hello World!"; 11</script> 12 13</body> 14</html>
XML DOM示例
加载XML文件并获取元素的值:
1<!DOCTYPE html> 2<html> 3<body> 4 5<p id="demo"></p> 6 7<script> 8var xhttp = new XMLHttpRequest(); 9xhttp.onreadystatechange = function() { 10 if (this.readyState == 4 && this.status == 200) { 11 myFunction(this); 12 } 13}; 14xhttp.open("GET", "books.xml", true); 15xhttp.send(); 16 17function myFunction(xml) { 18 var xmlDoc = xml.responseXML; 19 document.getElementById("demo").innerHTML = 20 xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue; 21} 22</script> 23 24</body> 25</html>
加载XML字符串并获取元素的值:
1<html> 2<body> 3 4<p id="demo"></p> 5 6<script> 7var text, parser, xmlDoc; 8 9text = "<bookstore><book>" + 10"<title>Everyday Italian</title>" + 11"<author>Giada De Laurentiis</author>" + 12"<year>2005</year>" + 13"</book></bookstore>"; 14 15parser = new DOMParser(); 16xmlDoc = parser.parseFromString(text,"text/xml"); 17 18document.getElementById("demo").innerHTML = 19xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue; 20</script> 21 22</body> 23</html>
DOM编程接口
DOM的编程接口由一组标准属性和方法定义。属性通常用于描述节点的特征,而方法通常用于执行与节点相关的操作。
属性的例子
x.nodeName- x的名称x.nodeValue- x的值x.parentNode- x的父节点x.childNodes- x的子节点x.attributes- x的属性节点
方法的例子
x.getElementsByTagName(name)- 获取指定标签名的所有元素x.appendChild(node)- 将一个子节点插入到xx.removeChild(node)- 从x中移除一个子节点
这些属性和方法使得通过编程可以访问和操作文档的各个部分。
XML DOM 节点
根据 XML DOM,XML 文档中的所有内容都是节点:
- 整个文档是一个文档节点
- 每个 XML 元素是一个元素节点
- XML 元素中的文本是文本节点
- 每个属性是一个属性节点
- 注释是注释节点
DOM 示例
看下面的 XML 文件(books.xml):
1<?xml version="1.0" encoding="UTF-8"?> 2<bookstore> 3 <book category="cooking"> 4 <title lang="en">Everyday Italian</title> 5 <author>Giada De Laurentiis</author> 6 <year>2005</year> 7 <price>30.00</price> 8 </book> 9 <book category="children"> 10 <title lang="en">Harry Potter</title> 11 <author>J.K. Rowling</author> 12 <year>2005</year> 13 <price>29.99</price> 14 </book> 15 <book category="web"> 16 <title lang="en">XQuery Kick Start</title> 17 <author>James McGovern</author> 18 <author>Per Bothner</author> 19 <author>Kurt Cagle</author> 20 <author>James Linn</author> 21 <author>Vaidyanathan Nagarajan</author> 22 <year>2003</year> 23 <price>49.99</price> 24 </book> 25 <book category="web" cover="paperback"> 26 <title lang="en">Learning XML</title> 27 <author>Erik T. Ray</author> 28 <year>2003</year> 29 <price>39.95</price> 30 </book> 31</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 片段:
1<bookstore> 2 <book category="cooking"> 3 <title lang="en">Everyday Italian</title> 4 <author>Giada De Laurentiis</author> 5 <year>2005</year> 6 <price>30.00</price> 7 </book> 8</bookstore>
在上述 XML 中,<title> 元素是 <book> 元素的第一个子节点,<price> 元素是 <book> 元素的最后一个子节点。
此外,<book> 元素是 <title>、<author>、<year> 和 <price> 元素的父节点。
XML DOM - 访问节点
使用 DOM,您可以访问 XML 文档中的每个节点。
访问节点
有三种方式可以访问节点:
- 使用
getElementsByTagName()方法 - 通过循环遍历节点树
- 通过导航节点树,使用节点之间的关系
getElementsByTagName() 方法
getElementsByTagName() 返回具有指定标签名的所有元素。
语法
1node.getElementsByTagName("tagname");
示例
以下示例返回 x 元素下的所有 <title> 元素:
1x.getElementsByTagName("title");
注意,上面的示例仅返回 x 节点下的 <title> 元素。要返回 XML 文档中的所有 <title> 元素,请使用:
1xmlDoc.getElementsByTagName("title");
其中 xmlDoc 是文档本身(文档节点)。
DOM 节点列表
getElementsByTagName() 方法返回一个节点列表。节点列表是节点的数组。
1x = xmlDoc.getElementsByTagName("title");
x 中的 <title> 元素可以通过索引号访问。要访问第三个 <title>,您可以这样写:
1y = x[2];
注意:索引从 0 开始。
DOM 节点列表长度
length 属性定义了节点列表的长度(节点数)。
您可以通过使用 length 属性循环遍历节点列表:
1var x = xmlDoc.getElementsByTagName("title"); 2 3for (i = 0; i < x.length; i++) { 4 // 对每个节点执行一些操作 5}
节点类型
XML 文档的 documentElement 属性是根节点。
节点的 nodeName 属性是节点的名称。
节点的 nodeType 属性是节点的类型
遍历节点
以下代码循环遍历根节点的子节点,这些子节点也是元素节点:
1txt = ""; 2x = xmlDoc.documentElement.childNodes; 3 4for (i = 0; i < x.length; i++) { 5 // 仅处理元素节点(类型 1) 6 if (x[i].nodeType == 1) { 7 txt += x[i].nodeName + "<br>"; 8 } 9}
示例解释:
- 假设您已经将 "books.xml" 加载到
xmlDoc中 - 获取根元素(
xmlDoc)的子节点 - 对于每个子节点,检查节点类型。如果节点类型是 "1",则它是一个元素节点
- 如果它是一个元素节点,则输出节点的名称
导航节点关系
以下代码使用节点之间的关系导航节点树:
1x = xmlDoc.getElementsByTagName("book")[0]; 2xlen = x.childNodes.length; 3y = x.firstChild; 4 5txt = ""; 6for (i = 0; i < xlen; i++) { 7 // 仅处理元素节点(类型 1) 8 if (y.nodeType == 1) { 9 txt += y.nodeName + "<br>"; 10 } 11 y = y.nextSibling; 12}
示例解释:
- 假设您已经将 "books.xml" 加载到
xmlDoc中 - 获取第一个
book元素的子节点 - 将 "y" 变量设置为第一个
book元素的第一个子节点 - 对于每个子节点(从第一个子节点 "y" 开始):
- 检查节点类型。如果节点类型是 "1",则它是一个元素节点
- 如果它是一个元素节点,则输出节点的名称
- 将 "y" 变量设置为下一个兄弟节点,并再次运行循环
XML DOM 节点信息
nodeName 属性
nodeName 属性指定节点的名称。
nodeName是只读的。- 元素节点的
nodeName与标签名相同。 - 属性节点的
nodeName是属性名。 - 文本节点的
nodeName始终是 #text。 - 文档节点的
nodeName始终是 #document。
nodeValue 属性
nodeValue 属性指定节点的值。
- 元素节点的
nodeValue是未定义的。 - 文本节点的
nodeValue是文本本身。 - 属性节点的
nodeValue是属性值。
获取元素的值
以下代码检索第一个 <title> 元素的文本节点值:
1var x = xmlDoc.getElementsByTagName("title")[0].childNodes[0]; 2var txt = x.nodeValue;
结果:txt = "Everyday Italian"
示例解释:
- 假设您已经将
books.xml加载到xmlDoc中。 - 获取第一个
<title>元素节点的文本节点。 - 将
txt变量设置为文本节点的值。
更改元素的值
以下代码更改了第一个 <title> 元素的文本节点值:
1var x = xmlDoc.getElementsByTagName("title")[0].childNodes[0]; 2x.nodeValue = "Easy Cooking";
示例解释:
- 假设您已经将
books.xml加载到xmlDoc中。 - 获取第一个
<title>元素节点的文本节点。 - 将文本节点的值更改为 "Easy Cooking"。
nodeType 属性
nodeType 属性指定节点的类型。
nodeType是只读的。- 最重要的节点类型是:
- 元素:1
- 属性:2
- 文本:3
- 注释:8
- 文档:9
DOM 属性列表(命名节点映射)
元素节点的 attributes 属性返回属性节点的列表。
这称为命名节点映射,与节点列表类似,只是在方法和属性上有一些差异。
属性列表会自我更新。如果删除或添加了属性,列表会自动更新。
此代码片段从 "books.xml" 中的第一个 <book> 元素返回属性节点的列表:
1x = xmlDoc.getElementsByTagName('book')[0].attributes;
执行上述代码后,x.length 是属性的数量,x.getNamedItem() 可用于返回一个属性节点。
此代码片段获取书籍的 "category" 属性值和属性列表的数量:
1x = xmlDoc.getElementsByTagName("book")[0].attributes; 2 3txt = x.getNamedItem("category").nodeValue + " " + x.length;
输出:
- cooking 1
示例解释:
- 假设
books.xml已加载到xmlDoc中。 - 设置
x变量以保存第一个<book>元素的所有属性的列表。 - 获取 "category" 属性的值和属性列表的长度。
最后
为了方便其他设备和平台的小伙伴观看往期文章:
微信公众号搜索:Let us Coding,关注后即可获取最新文章推送
看完如果觉得有帮助,欢迎点赞、收藏、关注
