Ajax - 将响应解析为XML

 

3.1.2  将响应解析为XML
你已经了解到,服务器不一定按XML格式发送响应。只要 Content-Type响应首部正确地设置为text/plain(如果是XML,Content-Type响应首部则是text/xml),将响应作为简单文本发送是完全可以的。复杂的数据结构就很适合以XML格式发送。对于导航XML文档以及修改XML文档的结构和内容,当前浏览器已经提供了很好的支持。
浏览器到底怎么处理服务器返回的XML呢?当前浏览器把XML看作是遵循W3C DOM的XML文档。W3C DOM指定了一组很丰富的API,可用于搜索和处理XML文档。DOM兼容的浏览器必须实现这些API,而且不允许有自定义的行为,这样就能尽可能地改善脚本在不同浏览器之间的可移植性。
W3C DOM
W3C DOM到底是什么?W3C主页提供了清晰的定义:
文档对象模型(DOM )是与平台和语言无关的接口,允许程序和脚本动态地访问和更新文档的内容、结构和样式。文档可以进一步处理,处理的结果可以放回到所提供的页面中。
不仅如此,W3C还解释了为什么要定义标准的DOM。W3C从其成员处收到了大量请求,这些请求都是关于将XML和HTML文档的对象模型提供给脚本所要采用的方法。提案并没有提出任何新的标记或样式表技术,而只是力图确保这些可互操作而且与脚本语言无关的解决方案能得到共识,并为开发社区所采纳。简单地说,W3C DOM标准的目的是尽量避免20世纪90年代末的脚本恶梦,那时相互竞争的浏览器都有自己专用的对象模型,而且通常都是不兼容的,这就使得实现跨平台的脚本极其困难。
W3C DOM和JavaScript
W3C DOM JavaScript 很容易混淆不清。 DOM 是面向 HTML XML 文档的 API ,为文档提供了结构化表示,并定义了如何通过脚本来访问文档结构。 JavaScript 则是 用于 访问和处理 DOM 的语言。如果没有 DOM JavaScript 根本没有 Web 页面和构成页面元素的概念。文档中的每个元素都是 DOM 的一部分,这就使得 JavaScript 可以访问元素的属性和方法。
DOM独立于具体的编程语言,通常通过JavaScript访问DOM,不过并不严格要求这样。可以使用任何脚本语言来访问DOM,这要归功于其一致的API。表3-1列出了DOM元素的一些有用的属性,表3-2列出了一些有用的方法。
表3-1  用于处理XML文档的DOM元素属性
属性名
描述
childNodes
返回当前元素所有子元素的数组
firstChild
返回当前元素的第一个下级子元素
lastChild
返回当前元素的最后一个子元素
nextSibling
返回紧跟在当前元素后面的元素
nodeValue
指定表示元素值的读 / 写属性
parentNode
返回元素的父节点
previousSibling
返回紧邻当前元素之前的元素
表3-2 用于遍历XML文档的DOM元素方法
方法名
描述
getElementById(id) (document)
获取有指定惟一 ID 属性值文档中的元素
getElementsByTagName(name)
返回当前元素中有指定标记名的子元素的数组
hasChildNodes()
返回一个布尔值,指示元素是否有子元素
getAttribute(name)
返回元素的属性值,属性由 name 指定
有了W3C DOM,就能编写简单的跨浏览器脚本,从而充分利用XML的强大功能和灵活性,将XML作为浏览器和服务器之间的通信介质。
从下面的例子可以看到,使用遵循W3C DOM的JavaScript来读取XML文档是何等简单。代码清单3-3显示了服务器向浏览器返回的XML文档的内容。这是一个简单的美国州名列表,各个州按地区划分。
代码清单3-3  服务器返回的美国州名列表
<? xml version="1.0" encoding="UTF-8" ?>
< states >
    
< north >
        
< state > Minnesota </ state >
        
< state > Iowa </ state >
        
< state > North Dakota </ state >
    
</ north >
    
< south >
        
< state > Texas </ state >
        
< state > Oklahoma </ state >
        
< state > Louisiana </ state >
    
</ south >
    
< east >
        
< state > New York </ state >
        
< state > North Carolina </ state >
        
< state > Massachusetts </ state >
    
</ east >
    
< west >
        
< state > California </ state >
        
< state > Oregon </ state >
        
< state > Nevada </ state >
    
</ west >
</ states >
在浏览器上会生成具有两个按钮的HTML页面。点击第一个按钮,将从服务器加载XML文档,然后在警告框中显示列于文档中的所有州。点击第二个按钮也会从服务器加载XML文档,不过只在警告框中显示北部地区的各个州(见图3-2)。
图3-2  点击页面上的任何一个按钮都会从服务器加载XML文档,并在警告框中显示适当的结果
代码清单3-4显示了 parseXML.html
代码清单 3-4   parseXML.html
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
>  
< html  xmlns ="http://www.w3.org/1999/xhtml" >
< head >
< title > Parsing XML Responses with the W3C DOM </ title >
 
< script  type ="text/javascript" >
var  xmlHttp;
var  requestType  =   "" ;
 
function  createXMLHttpRequest() {
    
if  (window.ActiveXObject) {
        xmlHttp 
=   new  ActiveXObject( " Microsoft.XMLHTTP " );
    }
    
else   if  (window.XMLHttpRequest) {
        xmlHttp 
=   new  XMLHttpRequest();
    }
}
 
function  startRequest(requestedList) {
    requestType 
=  requestedList;
    createXMLHttpRequest();
    xmlHttp.onreadystatechange 
=  handleStateChange;
    xmlHttp.open(
" GET " " parseXML.xml " true );
    xmlHttp.send(
null );
}
 
function  handleStateChange() {
    
if (xmlHttp.readyState  ==   4 ) {
        
if (xmlHttp.status  ==   200 ) {
            
if (requestType  ==   " north " ) {
                listNorthStates();
            }
            
else   if (requestType  ==   " all " ) {
                listAllStates();
            }
        }
    }
}
 
function  listNorthStates() {
    
var  xmlDoc  =  xmlHttp.responseXML;
    
var  northNode  =  xmlDoc.getElementsByTagName( " north " )[ 0 ];
 
    
var  out  =   " Northern States " ;
    
var  northStates  =  northNode.getElementsByTagName( " state " );
 
    outputList(
" Northern States " , northStates);
}
 
function  listAllStates() {
    
var  xmlDoc  =  xmlHttp.responseXML;
    
var  allStates  =  xmlDoc.getElementsByTagName( " state " );
 
    outputList(
" All States in Document " , allStates);
}
 
function  outputList(title, states) {
    
var  out  =  title;
    
var  currentState  =   null ;
    
for ( var  i  =   0 ; i  <  states.length; i ++ ) {
        currentState 
=  states[i];
        out 
=  out  +   " "   +  currentState.childNodes[ 0 ].nodeValue;
    }
    alert(out);
}
</ script >
</ head >
 
< body >
    
< h1 > Process XML Document of U.S. States </ h1 >
    
< br />< br />
    
< form  action ="#" >
        
< input  type ="button"  value ="View All Listed States"
                onclick
="startRequest('all');" />
        
< br />< br />
        
< input  type ="button"  value ="View All Listed Northern States"
                  onclick
="startRequest('north');" />
    
</ form >
</ body >
</ html >
以上脚本从服务器获取XML文档并加以处理,它与前面看到的例子很相似,不过前面的例子只是将响应处理为简单文本。关键区别就在于 listNorthStateslistAllStates函数。前面的例子从XMLHttpRequest对象获取服务器响应,并使用XMLHttpRequest对象的 responseText属性将响应获取为文本。 listNorthStateslistAllStates函数则不同,它们使用了XMLHttpRequest对象的 responseXML属性,将结果获取为XML文档,这样一来,你就可以使用W3C DOM方法来遍历XML文档了。
仔细研究一下 listAllStates函数。它首先创建了一个局部变量,名为 xmlDoc,并将这个变量初始化设置为服务器返回的XML文档,这个XML文档是使用XMLHttpRequest对象的 responseXML属性得到的。利用XML文档的 getElementsByTagName方法可以获取文档中所有标记名为 state的元素。 getElementsByTagName方法返回了包含所有 state元素的数组,这个数组将赋给名为 allStates的局部变量。
从XML文档获取了所有 state元素之后, listAllStates函数调用 outputList函数,并在警告框中显示这些 state元素。 listAllStates方法将迭代处理 state元素的数组,将各元素的相应州名逐个追加到一个串中,这个串最后将显示在警告框中。
有一点要特别注意,即 如何从 state元素获取州名。你可能认为, state元素会简单地提供属性或方法来得到这个元素的文本,但并非如此。
表示州名的文本实际上是 state元素的子元素。在XML文档中,文本本身被认为是一个节点,而且必须是另外某个元素的子元素。由于表示州名的文本实际上是 state元素的子元素,所以必须先从 state元素获取文本元素,再从这个文本元素得到其文本内容。
outputList函数的工作就是如此。它迭代处理数组中的所有元素,将当前元素赋给 currentState变量。因为表示州名的文本元素总是 state元素的第一个子元素,所以可以使用 childNodes属性来得到文本元素。一旦有了具体的文本元素,就可以使用 nodeValue属性返回表示州名的文本内容。
listNorthStates函数与 listAllStates是类似的,只不过增加了一个小技巧。你只想得到北部地区的州,而不是所有州。为此,首先使用 getElementsByTagName方法获取 north标记,从而获得XML文档中的 north元素。因为文档只包含一个 north元素,而且 getElementsByTagName方法总是返回一个数组,所以要用 [0]记法来抽出 north元素。这是因为,在 getElementsByTagName方法返回的数组中, north元素处在第一个位置上(也是惟一的位 置)。既然有了 north 元素,接下来调用 north 元素的 getElementsByTagName 方法,就可以得到 north 元素的 state 子元素。有了 north 元素所有 state 子元素的数组后,再使用 outputList方法在警告框中显示这些州名。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值