和JavaScript一起使用XML

XML是用户定义的标签组成的一种语言。由于标签是用户定义的,XML常常用做交换数据的一种方法。对于JavaScript程序员来说,一个重要的考虑是,XML是缩略语AJAXAsynchronous JavaScript and XML)中的XAJAX已经成为创建交互的Web应用的一种非常流行的方法。我们将在本书第18章和第19章学习有关AJAX的更多内容。

XMLW3C定义的一个开发的标准,并且当前处于第4版。本节将简要地介绍XML,因为它很适合于JavaScript。关于XML的更多信息,可以在XML Working GroupWeb站点http://www.w3.org/XML/Core/或者MicrosoftWeb站点http://msdn.microsoft.com/xml/找到。

17.1.1 XML文档的一个例子

XML文档由一个文档结构中的元素组成。这些元素有它们自己的语法规则,包括它们需要一个开始标签和一个结束标签。对于Web程序员,这看上去和一个文档(标签之间的文本)有点相似。下面是XML文档的一个例子,它作为books.xml提供于随书光盘的Chapter17文件夹下。

<books>

<book>

<title>MySQL Bible</title>

<author>Steve Suehring</author>

<isbn>9780764549328</isbn>

<publisher>Wiley Publishing Inc.</publisher>

</book>

<book>

<title>JavaScript Step by Step</title>

<author>Steve Suehring</author>

<isbn>9780735624498</isbn>

<publisher>Microsoft Press</publisher>

</book>

</books>

文档的结构作为一个整体,需要满足某些条件,才能够算是格式良好的文档。正如前面的例子所示,每个元素都有自己的开始标签,其后跟着一个相应的结束标签。元素也可以相互嵌套。很多这样的规则和HTML的规则类似。

XML文档也可以包含属性,因此,如下的形式也是有效的:

<?xml version="1.0"?>

<book title="JavaScript Step by Step" author="Steve Suehring" isbn="9780735624498"

publisher="Microsoft Press" />

17.1.2 使用JavaScript载入一个XML文档

可以使用JavaScript载入和操作XML文档。本节介绍如何做到这点。

导入文档

对于支持W3C模型的浏览器,使用document.implementation.createDocument()函数来请求XML文档并导入到JavaScript中;而对于Microsoft Windows Internet Explore,则是使用Microsoft.XMLDOM对象。和其他的不兼容性一样,这也意味着JavaScript程序员在编写代码时需要了解并考虑到这一区别。

例如,如下的代码创建了可以用来载入和操作XML文档的一个对象:

if (typeof document.implementation.createDocument != "undefined") {

docObj = document.implementation.createDocument("", "", null);

}

else if (window.ActiveXObject) {

docObj = new ActiveXObject("Microsoft.XMLDOM");

}

document.implementation.createDocument()函数接受3个参数:指定文档的命名空间的一个命名空间URL,根标签名和一个doc类型。实际上,你将发现这些参数保持未定义或者空,如例子所示。

对于Windows Internet ExplorerMicrosoft.XMLDOM对象必须用于此目的。一旦创建了docObj对象,它可以用来载入一个XML文档。在这个例子中,载入了一个名为books.xmlXML文档。

docObj.load("books.xml");

显示文档

可以把一个函数绑定到XML文档对象的onload事件(对于W3C兼容的浏览器)或onreadystatechange事件(对于Windows Internet Explorer)。然后,绑定的函数可以用来处理XML文档的内容。在这个小节,我们将介绍如何显示XML文档。

绑定一个函数到文档的load事件,这是解析XML的一个必需步骤。

对于W3C兼容的浏览器,使用onload事件。给前面的例子添加一个名为displayData()onload事件处理程序,如下所示:

if (typeof document.implementation.createDocument != "undefined") {

docObj = document.implementation.createDocument("", "", null);

docObj.onload = displayData;

}

对于Windows Internet Explorer,查看readyState属性来检查所请求文档的当前状态。如果readyState的值是4,那么,文档已经载入并且由此可以处理。对于Windows Internet Explorer,一个函数绑定到onreadystatechange事件。再次,继续前面的例子并且把一个displayData()函数绑定到onreadystatechange事件,如下所示:

else if (window.ActiveXObject) {

docObj = new ActiveXObject("Microsoft.XMLDOM");

docObj.onreadystatechange = function () {

if (docObj.readyState == 4) displayData()

};

}

readyState属性是一个整数,保存了5个值中的1个,表示请求处理的文档的当前状态。表17-1给出了值和相应的说明。

17-1 readyState属性

说明

0

未初始化。打开了,但还没有调用

1

打开。初始化了,但还没有发送

2

发送。请求已经发送

3

接受。响应已经激活正在接受

4

载入。响应已经完全接受

18章将介绍readyState属性和onreadystatechange事件的更多属性。现在,知道readyState4以内的数字相关就足够了。在文档载入的时候试图使用它或访问它,例如,当readyState等于3的时候,将会导致失败。

XML数据有时候最好以一个表格或数据表的格式来呈现。图17-1显示了在Excel 2007中的books.xml文件。

17-1 显示为数据表的一个XML文件

XML数据有时候可以显示于数据表中,例如,你已经见到的那个。一个HTML表格对于在浏览器中展示同样的数据也是有帮助的。在很大程度上,使用JavaScript来显示XML数据需要DOM的知识,但是不需要载入文档本身以外的其他特殊的函数或方法,正如你已经见到的那样。

显示一个XML文档中的节点和孩子节点,需要遍历文档的层级并且构建输出文档。下面显示的函数就是做这件事情的,通过遍历一个分层的XML文档来将其数据显示于一个HTML表格中。这段代码继续已经介绍的例子,其中创建了一个docObj对象,并且用一个名为books.xmlXML文档来载入:

function displayData() {

var xmlEl = docObj.getElementsByTagName("book");

var table = document.createElement("table");

table.border = "1";

var tbody = document.createElement("tbody");

// Append the body to the table

table.appendChild(tbody);

var row = document.createElement("tr");

// Append the row to the body

tbody.appendChild(row);

// Create table row

for (i = 0; i < xmlEl.length; i++) {

var row = document.createElement("tr");

// Create the row/td elements

for (j = 0; j < xmlEl[i].childNodes.length; j++) {

// Skip it if the type is not 1

if (xmlEl[i].childNodes[j].nodeType != 1) {

continue;

}

// Insert the actual text/data from the XML document.

var td = document.createElement("td");

var xmlData =

document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);

td.appendChild(xmlData);

row.appendChild(td);

}

tbody.appendChild(row);

}

document.getElementById("xmldata").appendChild(table);

}

把所有这些放入到一个Web页面中,意味着把载入和显示XML文件的函数绑定到一个事件。在程序清单17-1中(作为books.htm文件包含在随书光盘中),创建了一个名为getXML的新函数并且将其绑定到了window对象的onload事件。绑定事件的代码用粗体显示。

程序清单17-1 在一个HTML表格中显示XML数据

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/

strict.dtd">

<html>

<head>

<title>Books</title>

</head>

<body>

<div id="xmldata"></div>

<script type="text/javascript">

window.onload = getXML;

function displayData() {

var xmlEl = docObj.getElementsByTagName("book");

var table = document.createElement("table");

table.border = "1";

// Append the body to the table

// Create table row

for (i = 0; i < xmlEl.length; i++) {

var tbody = document.createElement("tbody");

table.appendChild(tbody);

var row = document.createElement("tr");

// Create the row/td elements

for (j = 0; j < xmlEl[i].childNodes.length; j++) {

// Skip it if the type is not 1

if (xmlEl[i].childNodes[j].nodeType != 1) {

continue;

}

// Insert the actual text/data from the XML document.

var td = document.createElement("td");

var xmlData =

document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);

td.appendChild(xmlData);

row.appendChild(td);

}

tbody.appendChild(row);

}

document.getElementById("xmldata").appendChild(table);

}

function getXML() {

if (typeof document.implementation.createDocument != "undefined") {

docObj = document.implementation.createDocument("", "", null);

docObj.onload = displayData;

}

else if (window.ActiveXObject) {

docObj = new ActiveXObject("Microsoft.XMLDOM");

docObj.onreadystatechange = function () {

if (docObj.readyState == 4) displayData()

};

}

docObj.load("books.xml");

}

</script>

</body>

</html>

通过Web浏览器查看的时候,这个表格就像数据表一样显示数据,如图17-2所示。

17-2 在一个HTML表中显示books.xml

查看程序清单17-1中的代码,可以看到一个大的for循环用来遍历XML层级,同时构建表的行。要注意的一点是,这个循环使用如下的代码只是查找XML文档中的Element节点:

// Skip it if the type is not 1

if (xmlEl[i].childNodes[j].nodeType != 1) {

continue;

}

nodeType等于1表示一个XML Element节点。如果循环中当前查看的节点的类型不是一个元素,我们可以移动到文档的下一个部分。

对于图17-2中的显示可能注意到的一个问题是,没有列标题。添加列标题意味着需要额外的一些代码。

从一个XML文档添加列标题

1.使用Microsoft Visual StudioEclipse或者其他编辑器,编辑Chapter17示例文件夹下的books.htm文件(当通过Web浏览器查看的时候,books.htm当前的样子如图17-2所示)。

2.books.htm中把如下粗体显示的代码添加到displayData()方法中:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/

strict.dtd">

<html>

<head>

<title>Books</title>

</head>

<body>

<div id="xmldata"></div>

<script type="text/javascript">

window.onload = getXML;

function displayData() {

var xmlEl = docObj.getElementsByTagName("book");

var table = document.createElement("table");

table.border = "1";

var tbody = document.createElement("tbody");

// Append the body to the table

table.appendChild(tbody);

var row = document.createElement("tr");

for (colHead = 0; colHead < xmlEl[0].childNodes.length; colHead++) {

if (xmlEl[0].childNodes[colHead].nodeType != 1) {

continue;

}

var tableHead = document.createElement("th");

var colName = document.createTextNode(xmlEl[0].childNodes[colHead].nodeName);

tableHead.appendChild(colName);

row.appendChild(tableHead);

}

// Append the row to the body

tbody.appendChild(row);

// Create table row

for (i = 0; i < xmlEl.length; i++) {

var row = document.createElement("tr");

// Create the row/td elements

for (j = 0; j < xmlEl[i].childNodes.length; j++) {

// Skip it if the type is not 1

if (xmlEl[i].childNodes[j].nodeType != 1) {

continue;

}

// Insert the actual text/data from the XML document.

var td = document.createElement("td");

var xmlData =

document.createTextNode(xmlEl[i].childNodes[j].firstChild.nodeValue);

td.appendChild(xmlData);

row.appendChild(td);

}

tbody.appendChild(row);

}

document.getElementById("xmldata").appendChild(table);

}

function getXML() {

if (typeof document.implementation.createDocument != "undefined") {

docObj = document.implementation.createDocument("", "", null);

docObj.onload = displayData;

}

else if (window.ActiveXObject) {

docObj = new ActiveXObject("Microsoft.XMLDOM");

docObj.onreadystatechange = function () {

if (docObj.readyState == 4) displayData()

};

}

docObj.load("books.xml");

}

</script>

</body>

</html>

8. Web浏览器中查看这个页面,如下图所示。

(原书315页图1

Excel 2007操作XML数据

Excel 2007有几项功能,使得操作XML数据很容易。使用Excel导入和导出XML数据都是可能的。实际上,当从Excel导出数据的时候,Excel对于XML文档没有添加专有性。下面是books.xml文件从Excel 2007导出后的样子(作为newbooks.xml文件包含在随书CD中):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<book>

<title>MySQL Bible</title>

<author>Steve Suehring</author>

<isbn>9780764549328</isbn>

<publisher>Wiley Publishing Inc.</publisher>

</book>

<book>

<title>JavaScript Step by Step</title>

<author>Steve Suehring</author>

<isbn>9780735624498</isbn>

<publisher>Microsoft Press</publisher>

</book>

</books>

由于Excel 2007XML友好的,在本章已经见到过的displayData()函数操作从Excel 2007导出的XML数据,而不做任何修改。对于过去操作专有格式数据的开发者来说,这带来了一大惊喜。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值