《HTML教程》-10.4教学材料_第1页
《HTML教程》-10.4教学材料_第2页
《HTML教程》-10.4教学材料_第3页
《HTML教程》-10.4教学材料_第4页
《HTML教程》-10.4教学材料_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

解析XML的方法(1)通过XML对象的getElementsByTagName()函数来获取XML中标记;(2)通过标记的getAttribute()函数获取标记的属性;(3)通过firstChild,lastChild和childNodes来取得标记的文本结点;(4)通过节点的(标记的)nodeValue取得标记里面的值。10.4.1准备xml文件新建JavaWeb项目,在WebContent目录下新建files文件夹,并在该文件夹下新建item.xml,输入以下内容[31]:<?xmlversion="1.0"encoding="UTF-8"?><itemid="itemGuitar"> <category> <name>Manufacturer</name> <value>Gibson</value> </category> <category> <name>Model</name> <value>Les

PaulStandard</value> </category> <category> <name>Description</name> <value>Pete

Townshendonceplayedthisguitarwhilehisownaxewasintheshophavingbitsofdrumkitremovedfromit.</value> </category> <category> <name>Price</name> <value>5695.99</value> </category><categorytype="list"><name>URLs</name><value>/</value><value>/wiki/Pete_Townshend</value></category></item>10.4.2准备js工具文件在WebContent目录下新建js文件夹,并拷贝utils.js文件。并在utils.js文件中添加以下代码,如代码清单10-1。清单10-1创建Ajax异步请求对象functioncreateRequest(){

varreq=null;

try{ req=newXMLHttpRequest(); }catch(e){ req=newActiveXObject('Microsoft.XMLHTTP'); }

returnreq;}异步请求对象的创建在第9章异步请求对象中已经详细的讲解,有不太清楚的地方,请参阅第9章9.1节。10.4.3请求并解析XML在js文件夹中新建request.js文件,完成如下操作。第1步:给btn按钮注册事件处理程序给按钮注册事件需要在网页初始化时完成,并采用自定义addEvent()函数实现对click事件的注册,代码如清单10-2所示。清单10-2给按钮注册单击事件//注册初始化函数window.onload=init;

//文档初始化functioninit(){

varbtn=document.getElementById("btn"); addEvent(btn,'click',requestXML,false);}第2步:编写requestXML事件处理代码编写10.2中注册的requestXML函数,实现对服务器的请求。首先,通过第2步创建的createRequest函数创建req对象。然后调用req的open方法,打开请求链接responseXML.jsp,并采用GET(第1个参数,注意这个参数全部字母要大写)和异步(第3个参数)方式请求服务器。第三,对readystatechange事件注册处理程序,准备解析服务器发回的数据。最后,调用req的send()方法发送请求。代码清单如10-3所示。清单10-3requestXML请求代码functionrequestXML(){ req=createRequest(); req.open('GET','responseXML.jsp',true); req.onreadystatechange=getDetail; req.send();}第3步:解析XML在此明确两个概念:结点和标记。这两个概念是一个事物的两个方面,在XML文档中就称之为标记,在XML对象中就称之为结点。就如同在HTML文档中,<p>称之为p标记,而在DOM对象中,则称为p结点。如10.2.1节中的<category>就称之为标记,而通过getElementsByTagName(“category”)获得的就称之为category结点。根据对10.2.1节XML文件的观察,我们可得到以下结论:(1)根标记为<item>。(2)根标记由若干个<category>标记组成。(3)<category>标记分为两种:一种是只包含一个<name>标记和一个<value>标记的<category>(如图9-1左上部分所示);另一种是包含一个<name>标记和多个<value>标记的<category>,它有一个特征就是包含type属性,且其值为list(如图10-1右上部分所示)。我们从XML中解析到数据以后要显示在HTML文档中,所以要把解析到的数据转换成HTML的DOM结点。我们的目标是把XML数据解析成如图10-1的下半部分所示的HTML结构。图10-1XML内容到HTML的转换把每个<category>中的数据包含在一个p段落中,其中<name>中的数据以<strong>标记进行强调显示,后跟<value>中的数据。如果<value>标记有多个,则把多个<value>中的数据显示在一个无序列表中。最后,把这个p段落标记放置到容器div中。结合要解析的XML结构特征和要显示的目标格式,可制订如下解析策略:首先,使用XML对象(异步请求对象的responseXML就表示XML对象)的getElementsByTagName()函数获取所有的<category>。其次,对于每个category结点对象,调用其getElementsByTagName()函数,获得name结点和value结点。第三,对于name结点,通过其firstChild属性(因为name标记只有一个文本结点。注意:不论文字有多长,都看作一个文本结点)的nodeValue属性,得到name结点中的数据。然后通过document对象的createElement()函数创建strong标记结点,通过createTextNode()创建name结点数据的文本结点对象,并通过strong结点的appendChild()函数将文本结点添加到strong标记中。第四,对于单个<value>标记,则取出它的数据创建文本结点,并添加到段落标记中。如果是多个<value>标记,则把每个value中的数据放置到li结点中,最后添加到ul结点中。具体解析XML的详细步骤和代码①清空容器我们要把解析后的数据放置到一个id为content的div标记中,每次添加数据之前必须把容器清空。因为,我们采用的是添加结点的方式添加数据的,所以如果显示前不清空容器,则会把每次显示的数据叠加,造成多余的数据,所以要清空容器。清空容器的代码如下://通过id获得容器对象varcon=document.getElementById("content"); //清空显示容器 for(vari=con.childNodes.length;i>0;i--){ //依次移除容器的最后一个孩子结点 con.removeChild(con.childNodes[i-1]); }②获取XML

要获取服务器传回的XML数据,只需要访问异步请求对象的responseXML属性即可,这个属性就指向XML对象,它本身是Document类型的对象。代码如下:varrespXML=req.responseXML;其中req是创建的异步请求对象。③

解析XML

首先,通过XML对象(此处为respXML)的getElementsByTagName()方法,获得XML文档中的所有<category>标记,如下面代码的注释①。然后,通过for循环遍历每个category结点,如下面代码注释②。第三,对两种category结点分别进行处理。对于只包含一个name结点和一个value结点的,分别读取name结点和value结点的值,然后把读取到的值创建DOM结点,插入到容器中,如下面代码的注释③。对于包含type属性的category,即包含一个name结点和多个value结点的category,则先处理name结点,然后通过category对象的getElementsByTagName()函数获得所有的value结点,并通过一个循环遍历所有的value结点,并通过value结点的firstChild属性的nodeValue属性读取value结点的值,如下面代码的注释④。综上所述,得到XML文档解析的框架(伪代码)如下。varcategories=respXML.getElementsByTagName("category"); //①for(vari=0;i<categories.length;i++){ //② //取第i个category varcategory=categories[i]; //解析name结点数据,并生成数据的DOM结点的代码//取第i个category的类型type varcategoryType=category.getAttribute("type");//分类型处理两种不同的category if(无type属性的category){ //③ //取得第i个category的value标记的数据 //category的value标记数据创建DOM结点 }else{ //④ //获取category的多个value标记的数据varvalues=category.getElementsByTagName("value"); for(varj=0;j<values.length;j++){ //取第j个value标记的内容 varval=values[j].firstChild.nodeValue; //生成DOM结点的代码 } //生成DOM结点的代码 }

}

④解析结点数据解析name结点的数据:首先通过category结点(name结点的父结点)的getElementsByTagName()函数,而不整个XML文档对象结点的getElementsByTagName()函数(这一点至关重要!),取得name结点。注意getElementsByTagName()函数返回的是一个数组,如果只取一个元素,要在后面加数组访问运算符[0]。然后,通过name结点的firstChild属性(此属性表示结点的第一个孩子结点)的nodeValue属性读取name结点的值,代码如下:varnameElement=category.getElementsByTagName("name")[0]; varcategoryName=nameElement.firstChild.nodeValue;解析value结点的数据,与解析name结点的数据类似,只不过通过getElementsByTagName()函数查找value结点,代码如下:varvalueElement=category.getElementsByTagName("value")[0]; varcategoryValue=valueElement.firstChild.nodeValue;解析多个value结点的数据:首先通过category结点(value结点的父结点)的getElementsByTagName()函数获取其下的所有value结点,这里得到一个结点的数组。然后通过循环遍历数组中的每个value结点,通过其firstChild属性的nodeValue属性读取其中的数据,代码如下:varvalues=category.getElementsByTagName("value"); for(varj=0;j<values.length;j++){ //取第j个value标记的内容 varval=values[j].firstChild.nodeValue; //生成DOM结点的代码 }

⑤生成HTMLDOM结点上一步得到的XML数据要显示在网页上,必须通过程序创建DOM结点的办法插入到网页中。根据我们对XML文档结构的分析和既定的显示格式,需要对name结点、value结点和多个value结点分别进行处理。对于name结点,我们显示格式是放在<strong>标记中,以强调的形式加以显示,然后再把<strong>标记添加到段落标记<p>中。首先,通过document对象的createElement()函数创建段落结点(相当于创建段落标记<p>),代码如下://创建段落标记 varp=document.createElement('p');第二,创建strong结点,代码如下://创建strong标记 varstrong=document.createElement("strong");第三,利用读取的name结点的数据创建文本结点。注意,name中的数据是没有冒号“:“的,要在创建文本结点时加上。从这一点可以说明,XML中没有的数据,而我们需要显示的,可以按照要求加上的。//创建名称文本结点 varnameText=document.createTextNode(categoryName+':');第四,将生成的文本结点添加到strong结点中。 strong.appendChild(nameText);第五,将strong标记添加到段落结点p中。p.appendChild(strong);对于value结点值的DOM对象的创建与name结点类似,在此不再赘述。下面讨论多个value结点的数据创建DOM的方法。根据显示要求,多个value值要放在一个无序列表中,也就是说,每个value结点值的DOM结点要放在li标记中。然后再把这个li标记放到ul标记中。首先,创建ul结点,代码如下:varlist=document.createElement("ul");第二,获得category结点的所有value结点。varvalues=category.getElementsByTagName("value");第三,循环遍历获得的values数组,逐一处理每个value结点。过程是:读取value结点的值(方法见④解析结点数据),然后将该值创建成文本结点,然后创建li结点,将文本结点添加到li结点中,最后把li结点添加到创建的ul结点中,代码如下://获取第i个category的所有value标记 for(varj=0;j<values.length;j++){ //取第j个value标记的内容 varval=values[j].firstChild.nodeValue; //创建文本结点 varvalText=document.createTextNode(val); //创建li结点 varli=document.createElement("li"); li.appendChild(valText); //将li结点添加到ul中 list.appendChild(li); }第四,将ul结点添加到段落标记p中,最后把段落标记添加到容器中,代码如下: con.appendChild(p); con.appendChild(list);综上所述,得到如清单10-4所示的解析XML的代码。10.4.4服务器响应XML数据

在项目WebContent目录上右键单击,选择“New→JSPFile”,新建responseXML.jsp文件,接收客户端发送的请求,并以XML数据进行响应。虽然服务器端编码不属于Ajax的范畴,但Ajax也不能脱离服务器端而独立存在。所以,服务器端编码是实用Ajax不可或缺的部分。在实际开发中,我们是将从数据库中提取出来的数据转换成XML格式的文档,然后再送往客户端,在此为了叙述和实例的简单性,我们把XML文档放到项目的files文件夹下的item.xml文件中。我们的任务是读取item.xml中的内容,再把读取到的内容送到客户端,步骤如下。第1步:文件定位

使用application内置对象的getRealPath()方法,获取files目录在磁盘上的绝对路径,便于下一步读取文件。代码如下:Stringpath=application.getRealPath("files");第2步:新建JavaFile对象引用文件

只需要用Java的关键字new一个File对象即可,比较简单,代码如下:FilexmlFile=newFile(path+"/item.xml");第3步:读取文件到缓冲区首先,创建指向文件的输入流,这里的文件就是上一步中创建的xmlFile文件对象。代码如下:InputStreamReaderis=newInputStreamReader(newFileInputStream(xmlFile));第二,创建按行读取的BufferedReader对象。由于我们的XML文档是以文本的形式存储于磁盘文件中,读取文本文件以按行读取为佳,所以我们创建按行读取的BufferedReader对象。BufferedReader对象的输入是上一步中创建的InputStreamReader的对象,即is。代码如下:BufferedReaderbr=newBufferedReader(is);第三,读取文件内容到缓冲区。我们把读取到的文件先放到StringBuilder缓冲区中,最后一次性写入客户端。所以先创建StringBuilder对象。接下来调用BufferedReader对象的(这里是br)readLine()方法一次读取一行,存放到临时字符串str中,然后去掉str中的首尾空格添加到StringBuilder中,直到读取到的行为null为止,读取完成。读取完成后关闭BufferedReader对象。代码如下://创建字符串缓冲区StringBuilder对象StringBuildersb=newStringBuilder();//临时存放读取的行文本的字符串变量 Stringstr=null;//一次读取一行,直到读取到的行为null,完成文件的读取 while((str=br.readLine())!=null){ //去掉首尾空格,添加到StringBuilder缓冲区中sb.append(str.trim()+"\n"); }//关闭BufferedReader对象 br.close();第四,把数据写入客户端。首先,把存放在StringBuilder对象(这里是sb)中的内容转换成字符串。只需要调用sb的toString()方法即可,代码如下:Stringcontent=sb.toString();第二,设置响应类型。

这一步最必须的,必须设置响应格式为text/xml;charset=UTF-8。text/xml说明服务器响应客户端的内容格式,这里说明响应的XML格式的文档。charset=UTF-8说明响应内容所使用的编码方式为UTF-8。UTF-8为通用的字符编码,一般项目中都采用这一编码方式。代码如下: response.setContentType("text/xml;charset=UTF-8");第三,将XML内容写入客户端。

这一步需要借助response内置对象的getWriter()方法获取PrintWriter对象(java.io.PrintWriter),该对象将字符串格式的内容写入到客户端。调用该对象的write()方法将响应内容写入客户端。写入完成后,必须调用flush()方法,该方法将JSP的缓冲区清空。最后调用close()方法,这个方法至关重要,一定要写,否则客户端收不到服务器的数据,而会一直等待!代码如下: PrintWriterpw=response.getWriter(); pw.write(content); pw.flush(); pw.close();综合上述代码,得到完整的服务器端响应XML的代码,如代码如清单10-5所示。10.4.5运行结果

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论