09-XML DOM
- XML DOM (XML Document Object Model) 定义了访问和操作 XML 文档的标准方法。
- DOM 把 XML 文档作为树结构来查看。能够通过 DOM 树来访问所有元素。可以修改或删除它们的内容,并创建新的元素。元素,它们的文本,以及它们的属性,都被认为是节点。
在下面的例子中,我们使用 DOM 引用从 元素中获取文本:
xmlDoc.getElementsByTagName("to")[0].childNodes[0].nodeValue
- xmlDoc -由解析器创建的 XML 文档
- getElementsByTagName(“to”)[0] - 第一个 元素
- childNodes[0] - 元素的第一个子元素(文本节点)
- nodeValue - 节点的值(文本本身)
HTML DOM
- HTML DOM (HTML Document Object Model) 定义了访问和操作 HTML 文档的标准方法。
可以通过 HTML DOM 访问所有 HTML 元素。
在下面的例子中,我们使用 DOM 引用来改变 id=”to” 的 HTML 元素的文本:
document.getElementById("to").innerHTML=
- document - HTML 文档
- getElementById(“to”) - 其中的 id=”to” 的 HTML 元素
innerHTML - HTML 元素的内部文本
<html>
<body>
<h1>W3School.com.cn Internal Note</h1>
<p><b>To:</b> <span id="to"></span><br />
<b>From:</b> <span id="from"></span><br />
<b>Message:</b> <span id="message"></span>
<script type="text/javascript"> if (window.XMLHttpRequest) {// code for IE7+,Firefox,Chrome,Opera,Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6,IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET","note.xml",false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; document.getElementById("to").innerHTML= xmlDoc.getElementsByTagName("to")[0].childNodes[0].nodeValue; document.getElementById("from").innerHTML= xmlDoc.getElementsByTagName("from")[0].childNodes[0].nodeValue; document.getElementById("message").innerHTML= xmlDoc.getElementsByTagName("body")[0].childNodes[0].nodeValue; </script>
</body>
</html>
XMl 文件
<?xml version="1.0" encoding="utf-8"?>
<note>
<to>George</to>
<from>john</from>
<heading>Reminder</heading>
<body>Don't forget the meeting this weekend</body>
</note>
结果:
W3School.com.cn Internal Note
To: George
From: John
Message: Don’t forget the meeting!
注释:
如需从 XML 中提取文本 “John”,语法是:
getElementsByTagName(“from”)[0].childNodes[0].nodeValue
在上例中,只有一个 标签,但是仍然需要规定数组的下标 [0],这是因为 getElementsByTagName() 方法会返回包含所有 节点的数组。
解析 XML 字符串 - 跨浏览器实例
下面的代码加载并解析一个 XML 字符串:
<html>
<body>
<h1>W3School.com.cn Internal Note</h1>
<p><b>To:</b> <span id="to"></span><br />
<b>From:</b> <span id="from"></span><br />
<b>Message:</b> <span id="message"></span></p>
<script> txt="<note>"; txt=txt+"<to>George</to>"; txt=txt+"<from>John</from>"; txt=txt+"<heading>Reminder</heading>"; txt=txt+"<body>Don't forget the meeting!</body>"; txt=txt+"</note>"; if (window.DOMParser) { parser=new DOMParser(); xmlDoc=parser.parseFromString(txt,"text/xml"); } else // Internet Explorer { xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); xmlDoc.async="false"; xmlDoc.loadXML(txt); } document.getElementById("to").innerHTML= xmlDoc.getElementsByTagName("to")[0].childNodes[0].nodeValue; document.getElementById("from").innerHTML= xmlDoc.getElementsByTagName("from")[0].childNodes[0].nodeValue; document.getElementById("message").innerHTML= xmlDoc.getElementsByTagName("body")[0].childNodes[0].nodeValue; </script>
</body>
</html>
结果:
W3School.com.cn Internal Note
To: George
From: John
Message: Don’t forget the meeting!
10-XML TO HTML
本例遍历一个 XML 文件 (catalog.xml),然后把每个 CD 元素显示为一个 HTML 表格行:
<html>
<body>
<script type="text/javascript"> if (window.XMLHttpRequest) {// code for IE7+,"catalog.xml",false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; document.write("<table border='1'>"); var x=xmlDoc.getElementsByTagName("CD"); for (i=0;i<x.length;i++) { document.write("<tr><td>"); document.write(x[i].getElementsByTagName("ARTIST[0].childNodes[0].nodeValue); document.write("</td><td>"); document.write(x[i].getElementsByTagName("TITLE[0].childNodes[0].nodeValue); document.write("</td></tr>"); } document.write("</table>"); </script>
</body>
</html>
catalog.xml
<!-- Edited with XML Spy v2007 (http://www.altova.com) -->
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
... more ...
</CATALOG>
例子解释:
- 检测浏览器,然后使用合适的解析器来加载 XML
- 创建一个 HTML 表格()
- 使用 getElementsByTagName() 来获得所有 XML 的 CD 节点
- 针对每个 CD 节点,把 ARTIST 和 TITLE 中的数据显示为表格数据
- 用 结束表格
11-XML 应用程序
- 在任意 HTML 元素中显示 XML 数据
<html>
<head>
<script type="text/javascript"> if (window.XMLHttpRequest) {// code for IE7+,"/example/xmle/cd_catalog.xml",false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; x=xmlDoc.getElementsByTagName("CD"); i=0; function displayCD() { artist=(x[i].getElementsByTagName("ARTIST"[0].childNodes[0].nodeValue); title=(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue); year=(x[i].getElementsByTagName("YEAR")[0].childNodes[0].nodeValue); txt="Artist: " + artist + "<br />Title: " + title + "<br />Year: "+ year; document.getElementById("showCD").innerHTML=txt; } </script>
</head>
<body onload="displayCD()">
<div id='showCD'></div>
</body>
</html>
- 添加导航脚本
<html>
<head>
<script type="text/javascript"> if (window.XMLHttpRequest) {// code for IE7+,false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; x=xmlDoc.getElementsByTagName("CD"); i=0; function displayCD() { artist=(x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue); title=(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue); year=(x[i].getElementsByTagName("YEAR")[0].childNodes[0].nodeValue); txt="Artist: " + artist + "<br />Title: " + title + "<br />Year: "+ year; document.getElementById("showCD").innerHTML=txt; } function next() { if (i<x.length-1) { i++; displayCD(); } } function prevIoUs() { if (i>0) { i--; displayCD(); } } </script>
</head>
<body onload="displayCD()">
<div id='showCD'></div><br />
<input type="button" onclick="prevIoUs()" value="<<" />
<input type="button" onclick="next()" value=">>" />
</body>
</html>
- 当点击 CD元素时显示专辑信息
<html>
<head>
<script type="text/javascript"> if (window.XMLHttpRequest) {// code for IE7+,false); xmlhttp.send(); xmlDoc=xmlhttp.responseXML; x=xmlDoc.getElementsByTagName("CD"); function displayCDInfo(i) { artist=(x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue); title=(x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue); year=(x[i].getElementsByTagName("YEAR")[0].childNodes[0].nodeValue); country=(x[i].getElementsByTagName("COUNTRY")[0].childNodes[0].nodeValue); company=(x[i].getElementsByTagName("COMPANY")[0].childNodes[0].nodeValue); price=(x[i].getElementsByTagName("PRICE")[0].childNodes[0].nodeValue); txt="Artist: "+artist+"<br />Title: "+title+"<br />Year: "+year+"<br />Country: "+country+"<br />Company: "+company+"<br />Price: "+price ; document.getElementById("showCD").innerHTML=txt; } </script>
</head>
<body>
<div id='showCD'>点击某个 CD 就可显示专辑信息:</div><br />
<script type="text/javascript"> document.write("<table border='1'>"); for (var i=0;i<x.length;i++) { document.write("<tr onclick='displayCDInfo(" + i + ")'>"); document.write("<td>"); document.write(x[i].getElementsByTagName("ARTIST[0].childNodes[0].nodeValue); document.write("</td><td>"); document.write(x[i].getElementsByTagName("TITLE[0].childNodes[0].nodeValue); document.write("</td></tr>"); } document.write("</table>"); </script>
</body>
</html>
12-XML 命名空间(XML Namespaces)
在 XML 中,元素名称是由开发者定义的,当两个不同的文档使用相同的元素名时,就会发生命名冲突。
这个 XML 文档携带着某个表格中的信息:
<table>
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>
这个 XML 文档携带有关桌子的信息(一件家具):
<table>
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
假如这两个 XML 文档被一起使用,由于两个文档都包含带有不同内容和定义的 <table> 元素,就会发生命名冲突。XML 解析器无法确定如何处理这类冲突。
使用前缀来避免命名冲突
<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
现在,命名冲突不存在了,这是由于两个文档都使用了不同的名称来命名它们的 <table> 元素 (<h:table> 和 <f:table>)。通过使用前缀,我们创建了两种不同类型的 <table> 元素。
使用命名空间(Namespaces)
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table xmlns:f="http://www.w3school.com.cn/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
与仅仅使用前缀不同,我们为 <table> 标签添加了一个 xmlns 属性,这样就为前缀赋予了一个与某个命名空间相关联的限定名称。
XML Namespace (xmlns) 属性
XML 命名空间属性被放置于元素的开始标签之中,并使用以下的语法:
xmlns:namespace-prefix="namespaceURI"
当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。 注释:用于标示命名空间的地址不会被解析器用于查找信息。其惟一的作用是赋予命名空间一个惟一的名称。不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。
统一资源标识符(Uniform Resource Identifier (URI))
统一资源标识符是一串可以标识因特网资源的字符。最常用的 URI 是用来标示因特网域名地址的统一资源定位器(URL)。另一个不那么常用的 URI 是统一资源命名(URN)。
默认的命名空间(Default Namespaces)
为元素定义默认的命名空间可以让我们省去在所有的子元素中使用前缀的工作。
请使用下面的语法:
xmlns="namespaceURI"
命名空间的实际应用
当开始使用 XSL 时,您不久就会看到实际使用中的命名空间。XSL 样式表用于将 XML 文档转换为其他格式,比如 HTML。如果您仔细观察下面的这个 XSL 文档,就会看到大多数的标签是HTML标签。非 HTML 的标签都有前缀 xsl。
13-XML CDATA
CDATA 部分中的所有内容都会被解析器忽略,CDATA 部分由
<![CDATA[" "]]>
XML 编码
XML 文档可以包含非 ASCII 字符,比如法语。
为了避免错误,需要规定 XML 编码,或者将 XML 文档存为 Unicode。
Windows 记事本
Windows 记事本默认会将文件保存为单字节的 ANSI (ASCII)。
如果选取文件菜单中的“另存为”命令,就可以规定双字节 Unicode (UTF-16)。
将下面的 XML 文件保存为 Unicode (注意文档不包含任何 encoding 属性):
<?xml version="1.0" encoding="UTF-8"?>
结论是:编码属性应当被指定为文档被保存时所使用的编码。我最好的避免错误的建议是:
14-XML DOM 高级
XML DOM (Document Object Model) 定义了访问和操作 XML 文档的标准方法。DOM 把 XML 文档视为一种树结构。通过这个 DOM 树,可以访问所有的元素。可以修改它们的内容(文本以及属性),而且可以创建新的元素。元素,以及它们的文本和属性,均被视为节点。
获取元素的值
下面的代码检索第一个 元素的文本值:
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];
txt=x.nodeValue;
txt=xmlDoc.getElementsByTagName("title[0].getAttribute("lang");
改变元素的值
下面的代码改变第一个 元素的文本值:
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];
x.nodeValue="Easy Cooking";
改变属性的值
x=xmlDoc.getElementsByTagName("book");
for(i=0;i<x.length;i++)
{
x[i].setAttribute("edition","first");
}
创建元素
createElement() 方法创建新的元素节点。
createTextNode() 方法创建新的文本节点。
appendChild() 方法向节点添加子节点(在最后一个子节点之后)。
如需创建带有文本内容的新元素,需要同时创建元素节点和文本节点。
下面的代码创建了一个元素 (),然后把它添加到第一个 元素中:
newel=xmlDoc.createElement("edition");
newtext=xmlDoc.createTextNode("First");
newel.appendChild(newtext);
x=xmlDoc.getElementsByTagName("book");
x[0].appendChild(newel);
删除元素
x=xmlDoc.getElementsByTagName("book")[0];
x.removeChild(x.childNodes[0]);