通过节点间的关系访问节点树中的节点,通常称为定位节点 ("navigating nodes")。
在 XML DOM 中,节点的关系被定义为节点的属性:
parentNodechildNodesfirstChildlastChildnextSiblingpreviousSibling下面的图像展示了 books.xml 中节点树的一个部分,并说明了节点之间的关系:
所有的节点都仅有一个父节点。下面的代码定位到 <book> 的父节点:
xmlDoc=loadXMLDoc("books.xml"); //获取第一个 <book> 元素 x=xmlDoc.getElementsByTagName("book")[0]; //输出 "x" 的父节点的节点名 document.write(x.parentNode.nodeName);Firefox,以及其他一些浏览器,把空的空白或换行当作文本节点,而 IE 不会这么做。
这会在使用下列属性使产生一个问题:firstChild、lastChild、nextSibling、previousSibling。
为了避免定位到空的文本节点(元素节点之间的空格和换行符号),我们使用一个函数来检查节点的类型:
function get_nextSibling(n) { y=n.nextSibling; //元素节点的类型是 1。如果同级节点不是元素节点,就移动到下一个节点,直到找到元素节点为止。通过这个办法,在 IE 和 Firefox 中,都可以得到相同的结果。 while (y.nodeType!=1) { y=y.nextSibling; } return y; }
有了上面的函数,我们就可以使用 get_nextSibling(node) 来代替 node.nextSibling 属性。
<html> <head> <script type="text/javascript" src="loadxmldoc.js"> </script> <script type="text/javascript"> //check if the first node is an element node function get_firstChild(n) { //获取第一个元素 y=n.firstChild; //获取最一个元素 //y=n.lastChild; //获取下一个同级元素 //y=n.nextSibling; //获取上一个同级元素 //y=n.previousSibling; while (y.nodeType!=1) { y=y.nextSibling; } return y; } </script> </head> <body> <script type="text/javascript"> xmlDoc=loadXMLDoc("books.xml"); x=get_firstChild(xmlDoc.getElementsByTagName("book")[0]); document.write(x.nodeName); </script> </body> </html>在 DOM 中,每种成分都是节点。元素节点没有文本值。
元素节点的文本存储在子节点中。该节点称为文本节点。
获取元素文本的方法,就是获取这个子节点(文本节点)的值。
getElementsByTagName() 方法返回包含拥有指定标签名的所有元素的节点列表,其中的元素的顺序是它们在源文档中出现的顺序。
xmlDoc=loadXMLDoc("books.xml"); x=xmlDoc.getElementsByTagName("title")[0];childNodes 属性返回子节点的列表。<title> 元素只有一个子节点,即一个文本节点。
下面的代码检索 <title> 元素的文本节点:
x=xmlDoc.getElementsByTagName("title")[0]; y=x.childNodes[0];nodeValue 属性返回文本节点的文本值:
x=xmlDoc.getElementsByTagName("title")[0]; y=x.childNodes[0]; txt=y.nodeValue;在 DOM 中,属性也是节点。与元素节点不同,属性节点拥有文本值。
获取属性的值的方法,就是获取它的文本值。
可以通过使用 getAttribute() 方法或属性节点的 nodeValue 属性来完成这个任务。
getAttribute() 方法返回属性的值。
下面的代码检索第一个 <title> 元素的 "lang" 属性的文本值:
xmlDoc=loadXMLDoc("books.xml"); //把 txt 变量设置为第一个 title 元素节点的 "lang" 属性的值 txt=xmlDoc.getElementsByTagName("title")[0].getAttribute("lang");getAttributeNode() 方法返回属性节点。
下面代码检索第一个 <title> 元素的 "lang" 属性的文本值:
xmlDoc=loadXMLDoc("books.xml"); //获取第一个 <title> 元素节点的 "lang" 属性节点 x=xmlDoc.getElementsByTagName("title")[0].getAttributeNode("lang"); //把 txt 变量设置为属性的值 txt=x.nodeValue;在 DOM 中,每种成分都是节点。元素节点没有文本值。
元素节点的文本存储在子节点中。该节点称为文本节点。
改变元素文本的方法,就是改变这个子节点(文本节点)的值。
nodeValue 属性可用于改变文本节点的值。
下面的代码片段改变了第一个 <title> 元素的文本节点值:
xmlDoc=loadXMLDoc("books.xml"); //获取第一个 <title> 元素的文本节点 x=xmlDoc.getElementsByTagName("title")[0].childNodes[0]; //把此文本节点的节点值更改为 "Hello World" x.nodeValue="Hello World";在 DOM 中,属性也是节点。与元素节点不同,属性节点拥有文本值。
改变属性的值的方法,就是改变它的文本值。
可以通过使用 setAttribute() 方法或属性节点的 nodeValue 属性来完成这个任务
setAttribute() 方法设置已有属性的值,或创建新属性。
下面的代码改变 <book> 元素的 category 属性:
xmlDoc=loadXMLDoc("books.xml"); //获取第一个 <book> 元素 x=xmlDoc.getElementsByTagName('book'); //把 "category" 属性的值更改为 "child" x[0].setAttribute("category","child");注释:如果属性节点不存在,则创建一个新属性(拥有指定的名称和值)。
nodeValue 属性可用于更改属性节点的值:
xmlDoc=loadXMLDoc("books.xml"); x=xmlDoc.getElementsByTagName("book")[0] //获取第一个 <book> 元素的 "category" 属性 y=x.getAttributeNode("category"); //把该属性节点的值更改为 "child" y.nodeValue="child";removeChild() 方法删除指定的节点。
当一个节点被删除时,其所有子节点也会被删除。
下面的代码片段将从载入的 xml 中删除第一个 <book> 元素:
xmlDoc=loadXMLDoc("books.xml"); //把变量 y 设置为要删除的元素节点 y=xmlDoc.getElementsByTagName("book")[0]; //通过使用 removeChild() 方法从父节点删除元素节点 xmlDoc.documentElement.removeChild(y);removeChild() 方法是唯一可以删除指定节点的方法。
当你已定位需要删除的节点时,就可以通过使用 parentNode 属性和 removeChild() 方法来删除此节点:
xmlDoc=loadXMLDoc("books.xml"); //把变量 y 设置为要删除的元素节点 x=xmlDoc.getElementsByTagName("book")[0]; //通过使用 parentNode 属性和 removeChild() 方法来删除此元素节点 x.parentNode.removeChild(x);removeChild() 方法可用于删除文本节点:
xmlDoc=loadXMLDoc("books.xml"); //把变量 x 设置为第一个 title 元素节点 x=xmlDoc.getElementsByTagName("title")[0]; //把变量 y 设置为 要删除的文本节点 y=x.childNodes[0]; //通过使用 removeChild() 方法从父节点删除节点 x.removeChild(y);注释:不太常用 removeChild() 从节点删除文本。可以使用 nodeValue 属性代替它。请看下一段。
nodeValue 属性可用于改变或清空文本节点的值:
xmlDoc=loadXMLDoc("books.xml"); //把变量 x 设置为第一个 title 元素的文本节点 x=xmlDoc.getElementsByTagName("title")[0].childNodes[0]; //使用 nodeValue 属性来清空文本节点的文本 x.nodeValue="";removeAttribute(name) 方法用于根据名称删除属性节点。
Example: removeAttribute('category')
下面的代码片段删除第一个 <book> 元素中的 "category" 属性:
xmlDoc=loadXMLDoc("books.xml"); //使用 getElementsByTagName() 来获取 book 节点 x=xmlDoc.getElementsByTagName("book"); //从第一个 book 元素节点中删除 "category" 属性 x[0].removeAttribute("category");removeAttributeNode(node) 方法通过使用 Node 对象作为参数,来删除属性节点。
Example: removeAttributeNode(x)
下面的代码片段删除所有 <book> 元素的所有属性:
xmlDoc=loadXMLDoc("books.xml"); //使用 getElementsByTagName() 来获取所有 book 节点 x=xmlDoc.getElementsByTagName("book"); //检查每个 book 元素是否拥有属性 for (i=0;i<x.length;i++) { //如果在某个 book 元素中存在属性,则删除该属性 while (x[i].attributes.length>0) { attnode=x[i].attributes[0]; old_att=x[i].removeAttributeNode(attnode); } }replaceChild() 方法用于替换节点。
下面的代码片段替换第一个 <book> 元素:
mlDoc=loadXMLDoc("books.xml"); x=xmlDoc.documentElement; //创建一个 book 元素、一个 title 元素,以及一个 text 节点 newNode=xmlDoc.createElement("book"); newTitle=xmlDoc.createElement("title"); newText=xmlDoc.createTextNode("Hello World"); //向 title 节点添加文本节点 newTitle.appendChild(newText); //向 book 节点添加 title 节点 newNode.appendChild(newTitle); y=xmlDoc.getElementsByTagName("book")[0]; //用这个新节点替换第一个 book 节点 x.replaceChild(newNode,y);replaceData() 方法用于替换文本节点中的数据。
replaceData() 方法有三个参数:
offset - 在何处开始替换字符。Offset 值以 0 开始。length - 要替换多少字符string - 要插入的字符串 xmlDoc=loadXMLDoc("books.xml"); //获取第一个 <title> 元素节点的文本节点 x=xmlDoc.getElementsByTagName("title")[0].childNodes[0]; //使用 replaceData 方法把文本节点的前 8 个字符替换为 "hello" x.replaceData(0,8,"hello");用 nodeValue 属性来替换文本节点中数据会更加容易。
下面的代码片段将用 "Easy Italian" 替换第一个 <title> 元素中的文本节点值:
xmlDoc=loadXMLDoc("books.xml"); x=xmlDoc.getElementsByTagName("title")[0].childNodes[0]; x.nodeValue="Hello World";createElement() 方法创建新的元素节点:
xmlDoc=loadXMLDoc("books.xml"); //创建一个新的元素节点 <edition> newel=xmlDoc.createElement("edition"); x=xmlDoc.getElementsByTagName("book")[0]; //向第一个 <book> 元素追加这个元素节点 x.appendChild(newel);createAttribute() 用于创建新的属性节点:
xmlDoc=loadXMLDoc("books.xml"); //创建一个新的属性节点 "edition" newatt=xmlDoc.createAttribute("edition"); newatt.nodeValue="first"; //向第一个 <title> 元素添加这个新的属性节点 x=xmlDoc.getElementsByTagName("title"); x[0].setAttributeNode(newatt);注释:如果该属性已存在,则被新属性替代。
由于 setAttribute() 可以在属性不存在的情况下创建新的属性,我们可以使用这个方法来创建新属性。
xmlDoc=loadXMLDoc("books.xml"); x=xmlDoc.getElementsByTagName('book'); //为第一个 <book> 元素设置(创建)值为 "first" 的属性 x[0].setAttribute("edition","first");createTextNode() 方法创建新的文本节点:
xmlDoc=loadXMLDoc("books.xml"); //创建一个新元素节点 <edition> newel=xmlDoc.createElement("edition"); //创建一个新的文本节点,其文本是 "first" newtext=xmlDoc.createTextNode("first"); //向这个元素节点追加新的文本节点 newel.appendChild(newtext); //向第一个 <book> 元素追加新的元素节点 x=xmlDoc.getElementsByTagName("book")[0]; x.appendChild(newel);createCDATASection() 方法创建一个新的 CDATA section 节点。
xmlDoc=loadXMLDoc("books.xml"); //创建一个新的 CDATA section 节点 newCDATA=xmlDoc.createCDATASection("Special Offer & Book Sale"); //向第一个 <book> 元素追加这个新的 CDATA section 节点 x=xmlDoc.getElementsByTagName("book")[0]; x.appendChild(newCDATA);createComment() 方法创建一个新的注释节点。
xmlDoc=loadXMLDoc("books.xml"); //创建一个新的注释节点 newComment=xmlDoc.createComment("Revised March 2008"); //把这个新的注释节点追加到第一个 <book> 元素 x=xmlDoc.getElementsByTagName("book")[0]; x.appendChild(newComment);appendChild() 方法向已存在的节点添加子节点。
新节点会添加(追加)到任何已存在的子节点之后。
注释:如果节点的位置很重要,请使用 insertBefore() 方法。
下面的代码片段创建一个元素(<edition>),并把它添加到第一个 <book> 元素最后一个子节点后面:
xmlDoc=loadXMLDoc("books.xml"); //创建一个新节点 <edition> newel=xmlDoc.createElement("edition"); //把这个节点追加到第一个 <book> 元素 x=xmlDoc.getElementsByTagName("book")[0]; x.appendChild(newel);insertBefore() 方法用于在指定的子节点之前插入节点。
在被添加的节点的位置很重要时,此方法很有用。
xmlDoc=loadXMLDoc("books.xml"); //创建一个新的元素节点 <book> newNode=xmlDoc.createElement("book"); //把这个节点插到最后一个 <book> 元素节点之前 x=xmlDoc.documentElement; y=xmlDoc.getElementsByTagName("book")[3]; x.insertBefore(newNode,y);注释:如果 insertBefore() 的第二个参数是 null,新节点将添加到最后一个已有的子节点之后。
x.insertBefore(newNode,null) 和 x.appendChild(newNode) 都可以向 x 追加一个新的子节点
addAtribute() 这个方法是不存在的。
如果属性不存在,则 setAttribute() 可创建一个新的属性:
xmlDoc=loadXMLDoc("books.xml"); //把第一个 <book> 元素的 "edition" 属性的值设置(创建)"first" x=xmlDoc.getElementsByTagName('book'); x[0].setAttribute("edition","first");注释:如果属性已存在,setAttribute() 方法将覆盖已有的值。
insertData() 方法将数据插入已有的文本节点中。
insertData() 方法有两个参数:
offset - 在何处开始插入字符(以 0 开始)string - 要插入的字符串下面的代码片段将把 "Easy" 添加到已加载的 XML 的第一个 <title> 元素的文本节点:
xmlDoc=loadXMLDoc("books.xml"); x=xmlDoc.getElementsByTagName("title")[0].childNodes[0]; x.insertData(0,"Hello ");cloneNode() 方法创建指定节点的副本。
cloneNode() 方法有一个参数(true 或 false)。该参数指示被复制的节点是否包括原节点的所有属性和子节点。
下面的代码片段拷贝第一个 <book> 节点,并把它追加到文档的根节点:
xmlDoc=loadXMLDoc("books.xml"); //获取要复制的节点 oldNode=xmlDoc.getElementsByTagName('book')[0]; //通过使用 cloneNode 方法把节点复制到 "newNode" 中 newNode=oldNode.cloneNode(true); //向 XML 文档的根节点追加新节点 xmlDoc.documentElement.appendChild(newNode); //输出文档中所有 book 的 title y=xmlDoc.getElementsByTagName("title"); for (i=0;i<y.length;i++) { document.write(y[i].childNodes[0].nodeValue); document.write("<br />"); } //输出: Harry Potter Everyday Italian XQuery Kick Start Learning XML Harry Potter