XMLDOM
Basic
文件物件模型(Document Object Model):是W3C组织推荐的处理可扩展置标语言(XML)的标准编程接口。
XML 文档对象模型定义访问和操作XML文档的标准方法。
XML Document Object Model 用于 XML 的标准对象模型, 用于 XML 的标准编程接口, 中立于平台和语言, W3C 的标准
W3C 文档对象模型(DOM)是一个使程序和脚本有能力动态地访问和更新文档的内容、结构以及样式的平台和语言中立的接口。
Three levels >Core DOM 用于任何结构化文档的标准模型 >XML DOM 用于XML文档的标准模型 >HTML DOM 用于 HTML的标准模型
节点 整个文档是一个文档节点, 每个 XML 标签是一个元素节点, 包含在 XML 元素中的文本是文本节点, 每一个 XML 属性是一个属性节点, 注释属于注释节点
>文本总是存储在文本节点中 <year>2005</year>,元素节点 <year>,拥有一个值为 "2005" 的文本节点。"2005" 不是 <year> 元素的值!
XML DOM 节点树 (node-tree) >树中的所有节点彼此之间都有关系
DOM 将 XML 文档作为一个树形结构,而树叶被定义为节点
父、子和同级节点
>在节点树中,顶端的节点成为根节点 >根节点之外的每个节点都有一个父节点 >节点可以有任何数量的子节点 >叶子是没有子节点的节点 >同级节点是拥有相同父节点的节点
父节点:Parent Node,子节点:Children Node,同级节点:Sibling Node
--Basic End---
Detail
解析 XML DOM
大多数浏览器都内建了供读取和操作 XML 的 XML 解析器。解析器把 XML 转换为 JavaScript 可存取的对象。解析器把 XML 读入内存,并把它转换为可被 JavaScript 访问的 XML DOM 对象
>微软的 XML 解析器与其他浏览器中的解析器是有差异的。微软的解析器支持对 XML 文件和 XML 字符串(文本)的加载,而其他浏览器使用单独的解析器。不过,所有的解析器都含有遍历 XML 树、访问、插入及删除节点的函数。
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");xmlDoc.async="false";xmlDoc.load("books.xml");
创建空的微软 XML 文档对象, 关闭异步加载,这样可确保在文档完整加载之前,解析器不会继续执行脚本, 告知解析器加载名为 "books.xml" 的文档
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");xmlDoc.async="false";xmlDoc.loadXML(txt);
loadXML() 方法用于加载字符串(文本),而 load() 用于加载文件
>Firefox 及其他浏览器中的 XML 解析器
xmlDoc=document.implementation.createDocument("","",null);xmlDoc.async="false";xmlDoc.load("books.xml");
parser=new DOMParser();xmlDoc=parser.parseFromString(txt,"text/xml");
>Chrome Issue
Google Chrome 下面不能使用load,下面的代码会报错:
xmlDoc=document.implementation.createDocument('', '', null);
xmlDoc.async=false;
xmlDoc.load(fileRoute); // Google Chrome不支持load
想要同时支持Google Chrome + FireFox , 使用下面的方法:
var xmlhttp = new window.XMLHttpRequest();
xmlhttp.open("GET",xmlsrc,false);
xmlhttp.send(null);
var xmlDoc = xmlhttp.responseXML.documentElement;
获取一个节点,使用:
var x=xmlDoc.getElementsByTagName("nodename");
读取节点的值,使用:
x[0..i].childNodes[0].nodeValue
Error: Access Across Domains
出于安全方面的原因,现代的浏览器不允许跨域的访问。这意味着,网页以及它试图加载的 XML 文件,都必须位于相同的服务器上。
xmlDoc.load() 将产生错误 "Access is denied"。
加载函数
DOMParser 对象解析 XML 文本并返回一个 XML Document 对象。要使用 DOMParser,使用不带参数的构造函数来实例化它,然后调用其 parseFromString() 方法:
var doc = (new DOMParser()).parseFromString(text)
IE 不支持 DOMParser 对象。相反,它支持使用 Document.loadXML() 的 XML 解析。
注意,XMLHttpRequest 对象也可以解析 XML 文档。参阅 XMLHttpRequest 的 responseXML 属性
属性和方法
>编程接口 DOM 把 XML 模拟为一系列节点接口。可通过 JavaScript 或其他编程语言来访问节点. 对 DOM 的编程接口是通过一套标准的属性("book")和方法(删除 "book" 节点)来定义的.
>属性 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 删除子节点
>example
txt=xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue
getElementsByTagName 是方法,而 childNodes 和 nodeValue 是属性, getElementsByTagName() 方法总是会返回数组
访问节点
>length
x=xmlDoc.getElementsByTagName("title");
for (i=0;i<x.length;i++)
{
document.write(x[i].childNodes[0].nodeValue);
document.write("<br />");
}
nodeType, nodeName
3个方法 getElementsByTagName(), 循环(遍历)节点树, 利用节点的关系在节点树中导航
>getElementsByTagName()
node.getElementsByTagName("tagname");
-example
x 元素下的所有 <title> 元素
x.getElementsByTagName("title");
XML 文档中的所有 <title> 元素
xmlDoc.getElementsByTagName("title");
DOM Node List
xmlDoc=loadXMLDoc("books.xml");x=xmlDoc.getElementsByTagName("title");
y=x[2];
Node Type
XML 文档的 documentElement 属性是根节点。节点的 nodeName 属性是节点的名称。节点的 nodeType 属性是节点的类型。
>Example 如果节点类型是 "1",则是元素节点
节点信息
节点的属性
>nodeName 只读的, 元素节点的 nodeName 与标签名相同, 属性节点的 nodeName 是属性的名称, 文本节点的 nodeName 永远是 #text, 文档节点的 nodeName 永远是 #document
>nodeValue 元素节点的 nodeValue 是 undefined, 文本节点的 nodeValue 是文本自身, 属性节点的 nodeValue 是属性的值
-获取元素的值
txt=x.nodeValue;
-更改元素的值
x.nodeValue="Easy Cooking";
-nodeType nodeType 属性规定节点的类型, nodeType 是只读的
元素类型 | 节点类型 |
---|---|
元素 | 1 |
属性 | 2 |
文本 | 3 |
注释 | 8 |
文档 | 9 |
DOM Attribute List (Named Node Map)
>元素节点的 attributes 属性返回属性节点的列表
x=xmlDoc.getElementsByTagName("book")[0].attributes;
遍历节点树
遍历 (Traverse) 意味着在节点树中进行循环或移动
// documentElement always represents the root node
x=xmlDoc.documentElement.childNodes;
for (i=0;i<x.length;i++){document.write(x[i].nodeName);document.write(": ");document.write(x[i].childNodes[0].nodeValue);document.write("<br />");}
浏览器差异
>所有现代浏览器都支持 W3C DOM 规范
区别: 加载 XML 的方式, 处理空白和换行的方式
空白和换行 CR/LF
XML 经常在节点之间含有换行或空白字符, Firefox,以及其他一些浏览器,会把空的空白或换行作为文本节点来处理,而 Internet Explorer 不会这样。
>CR/LF
http://www.cslog.cn/Content/cr-lf-crlf-new-line-enter
在文本处理中, CR, LF, CR/LF是不同操作系统上使用的换行符. Dos和windows采用回车+换行CR/LF表示下一行, 而UNIX/Linux采用换行符LF表示下一行,苹果机(MAC OS系统)则采用回车符CR表示下一行.
CR用符号’r’表示, 十进制ASCII代码是13, 十六进制代码为0x0D; LF使用’n’符号表示, ASCII代码是10, 十六制为0x0A. 所以Windows平台上换行在文本文件中是使用 0d 0a 两个字节表示, 而UNIX和苹果平台上换行则是使用0a或0d一个字节表示.
一般操作系统上的运行库会自动决定文本文件的换行格式. 如一个程序在windows上运行就生成CR/LF换行格式的文本文件,而在Linux上运行就生成LF格式换行的文本文件.
在一个平台上使用另一种换行符的文件文件可能会带来意想不到的问题, 特别是在编辑程序代码时. 有时候代码在编辑器中显示正常, 但在编辑时却会因为换行符问题而出错.
很多文本/代码编辑器带有换行符转换功能, 使用这个功能可以将文本文件中的换行符在不同格式单互换.
在不同平台间使用FTP软件传送文件时, 在ascii文本模式传输模式下, 一些FTP客户端程序会自动对换行格式进行转换. 经过这种传输的文件字节数可能会发生变化. 如果你不想ftp修改原文件, 可以使用bin模式(二进制模式)传输文本.
忽略节点间的空文本
元素节点的类型是 1
for (i=0;i<x.length;i++){ if (x[i].nodeType==1) {
// only process element nodes
document.write(x[i].nodeName); document.write("<br />"); } }
定位节点
通过节点间的关系访问节点树中的节点,通常称为定位节点 ("navigating nodes")
parentNode, childNodes, firstChild,lastChild, nextSibling, previousSibling
父节点 所有的节点都仅有一个父节点
x=xmlDoc.getElementsByTagName("book")[0];document.write(x.parentNode.nodeName);
避免空的文本节点
function get_nextSibling(n){y=n.nextSibling;while (y.nodeType!=1) { y=y.nextSibling; }return y;}
节点操作
获取节点值
nodeValue 属性用于获取节点的文本值。getAttribute() 方法返回属性的值。
获取元素的值
在 DOM 中,每种成分都是节点。元素节点没有文本值。元素节点的文本存储在子节点中。该节点称为文本节点。获取元素文本的方法,就是获取这个子节点(文本节点)的值。
getElementsByTagName() 方法返回包含拥有指定标签名的所有元素的节点列表,其中的元素的顺序是它们在源文档中出现的顺序。
x=xmlDoc.getElementsByTagName("title")[0];y=x.childNodes[0];txt=y.nodeValue;
获取属性的值
属性也是节点。与元素节点不同,属性节点拥有文本值。获取属性的值的方法,就是获取它的文本值。可以通过使用 getAttribute() 方法或属性节点的 nodeValue 属性来完成这个任务。
txt=xmlDoc.getElementsByTagName("title")[0].getAttribute("lang");
txt = "en"
>getAttributeNode()
x=xmlDoc.getElementsByTagName("title")[0].getAttributeNode("lang");txt=x.nodeValue;
改变节点值
nodeValue 属性用于改变节点值, setAttribute() 方法用于改变属性的值
改变元素的值
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];x.nodeValue="Hello World";
setAttribute()
x=xmlDoc.getElementsByTagName('book');x[0].setAttribute("category","child");
>如果属性节点不存在,则创建一个新属性(拥有指定的名称和值)
使用 nodeValue 改变属性
x=xmlDoc.getElementsByTagName("book")[0]y=x.getAttributeNode("category");y.nodeValue="child";
删除节点
removeChild() 方法删除指定节点。removeAttribute() 方法删除指定属性。
删除元素节点
y=xmlDoc.getElementsByTagName("book")[0];xmlDoc.documentElement.removeChild(y);
删除自身 - 删除当前的节点
removeChild() 方法是唯一可以删除指定节点的方法。
x.parentNode.removeChild(x);
删除文本节点
y=x.childNodes[0];x.removeChild(y);
不太常用 removeChild() 从节点删除文本。可以使用 nodeValue 属性代替它
清空文本节点
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];x.nodeValue="";
根据对象删除属性节点
removeAttributeNode(node) 方法通过使用 Node 对象作为参数,来删除属性节点。
for (i=0;i<x.length;i++){while (x[i].attributes.length>0) { attnode=x[i].attributes[0]; old_att=x[i].removeAttributeNode(attnode); }}
替换节点
replaceChild() 方法替换指定节点。nodeValue 属性替换文本节点中的文本。
替换元素节点
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() 方法用于替换文本节点中的数据。
参数 offset - 在何处开始替换字符。Offset 值以 0 开始。length - 要替换多少字符。string - 要插入的字符串
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];x.replaceData(0,8,"hello");
创建节点
创建新的元素节点 createElement()
newel=xmlDoc.createElement("edition"); x=xmlDoc.getElementsByTagName("book")[0]; x.appendChild(newel);
创建新的属性节点 createAttribute()
newatt=xmlDoc.createAttribute("edition"); newatt.nodeValue="first"; x=xmlDoc.getElementsByTagName("title"); x[0].setAttributeNode(newatt);
通过使用 setAttribute() 来创建属性
setAttribute() 可以在属性不存在的情况下创建新的属性
x=xmlDoc.getElementsByTagName('book'); x[0].setAttribute("edition","first");
创建文本节点 createTextNode()
newel=xmlDoc.createElement("edition"); newtext=xmlDoc.createTextNode("first"); newel.appendChild(newtext); x=xmlDoc.getElementsByTagName("book")[0]; x.appendChild(newel);
创建一个 CDATA Section 节点 createCDATASection()
创建注释节点 createComment()
添加节点
appendChild() 方法向已存在的节点添加子节点。新节点会添加(追加)到任何已存在的子节点之后。
>如果节点的位置很重要,请使用 insertBefore() 方法。
newNode=xmlDoc.createElement("book"); x=xmlDoc.documentElement; y=xmlDoc.getElementsByTagName("book")[3]; x.insertBefore(newNode,y);
如果 insertBefore() 的第二个参数是 null,新节点将添加到最后一个已有的子节点之后。
x.insertBefore(newNode,null) 和 x.appendChild(newNode) 都可以向 x 追加一个新的子节点。
添加新属性
如果属性不存在,则 setAttribute() 可创建一个新的属性, 如果属性已存在,setAttribute() 方法将覆盖已有的值
向文本节点添加文本 - insertData()
将数据插入已有的文本节点中。
>参数 offset - 在何处开始插入字符(以 0 开始)string - 要插入的字符串
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0]; x.insertData(0,"Hello ");
克隆节点
复制节点 cloneNode() 方法创建指定节点的副本。
参数(true 或 false)。该参数指示被复制的节点是否包括原节点的所有属性和子节点
oldNode=xmlDoc.getElementsByTagName('book')[0]; newNode=oldNode.cloneNode(true); xmlDoc.documentElement.appendChild(newNode);
XMLHttpRequest 对象
XMLHttpRequest 对象提供了在网页加载后与服务器进行通信的方法。所有现代的浏览器都支持 XMLHttpRequest 对象
在不重新加载页面的情况下更新网页, 在页面已加载后从服务器请求数据, 在页面已加载后从服务器接收数据, 在后台向服务器发送数据
http://www.w3school.com.cn/xmldom/dom_httprequest.asp
refer to AJAX
---Detail End---
Reference
DOMParser.parseFromString() 解析 XML 标记
parseFromString(text, contentType)
text 参数是要解析的 XML 标记。contentType 是文本的内容类型。可能是 "text/xml" 、"application/xml" 或 "application/xhtml+xml" 中的一个。注意,不支持 "text/html"。
>Return 保存 text 解析后表示的一个 Document 对象。参阅 Document.loadXML(),了解这个方法的一个特定于 IE 的替代。
参考手册
http://www.w3school.com.cn/htmldom/htmldom_reference.asp
---Reference End---
---XMLDOM End---
HTMLDOM
Basic
HTML DOM 定义了访问和操作HTML文档的标准方法。HTML DOM 把 HTML 文档呈现为带有元素、属性和文本的树结构(节点树)
(HTML Document Object Model)
HTML 文档中的每个成分都是一个节点。
Node 层次 节点彼此都有等级关系
HTML 文档中的所有节点组成了一个文档树(或节点树)。HTML 文档中的每个元素、属性、文本等都代表着树中的一个节点。树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止。
---Basic End---
Detail
文档树(节点数)
<html> <head> <title>DOM Tutorial</title> </head> <body> <h1>DOM Lesson one</h1> <p>Hello world!</p> </body> </html>
除文档节点之外的每个节点都有父节点。大部分元素节点都有子节点。当节点分享同一个父节点时,它们就是同辈(同级节点)
所有的文本节点都是 <html>节点的后代,而第一个文本节点是 <head> 节点的后代。所有的文本节点都可把 <html> 节点作为先辈节点。
访问节点
getElementById() 和 getElementsByTagName() 这两种方法,可查找整个 HTML 文档中的任何 HTML 元素。这两种方法会忽略文档的结构。
document.getElementById("ID");
>getElementById() 无法工作在 XML 中。在 XML 文档中,您必须通过拥有类型 id 的属性来进行搜索,而此类型必须在 XML DTD 中进行声明。
document.getElementsByTagName("标签名称");
document.getElementById('ID').getElementsByTagName("标签名称");
>Example 返回所有 <p> 元素的一个节点列表,且这些 <p> 元素必须是 id 为 "maindiv" 的元素的后代
document.getElementById('maindiv').getElementsByTagName("p");
节点列表(nodeList)
遍历节点列表
var x=document.getElementsByTagName("p"); for (var i=0;i<x.length;i++) { // do something with each paragraph }
var y=x[2];
parentNode、firstChild以及lastChild (refer to XMLDOM)
根节点
有两种特殊的文档属性可用来访问根节点:document.documentElement, document.body
第一个属性可返回存在于 XML 以及 HTML 文档中的文档根节点。
第二个属性是对 HTML 页面的特殊扩展,提供了对 <body> 标签的直接访问。
节点信息
nodeName(节点名称)nodeValue(节点值)nodeType(节点类型)
>nodeName 所包含的 XML 元素的标签名称永远是大写的
>nodeValue 属性对于文档节点和元素节点是不可用的。
HTML DOM 参考手册
http://www.w3school.com.cn/htmldom/htmldom_reference.asp
http://w3schools.com/jsref/default.asp
---Detail End---
---HTMLDOM End---