《HTML教程》-10.4教學(xué)材料_第1頁
《HTML教程》-10.4教學(xué)材料_第2頁
《HTML教程》-10.4教學(xué)材料_第3頁
《HTML教程》-10.4教學(xué)材料_第4頁
《HTML教程》-10.4教學(xué)材料_第5頁
已閱讀5頁,還剩65頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

解析XML的方法(1)通過XML對象的getElementsByTagName()函數(shù)來獲取XML中標(biāo)記;(2)通過標(biāo)記的getAttribute()函數(shù)獲取標(biāo)記的屬性;(3)通過firstChild,lastChild和childNodes來取得標(biāo)記的文本結(jié)點(diǎn);(4)通過節(jié)點(diǎn)的(標(biāo)記的)nodeValue取得標(biāo)記里面的值。10.4.1準(zhǔn)備xml文件新建JavaWeb項(xiàng)目,在WebContent目錄下新建files文件夾,并在該文件夾下新建item.xml,輸入以下內(nèi)容[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準(zhǔn)備js工具文件在WebContent目錄下新建js文件夾,并拷貝utils.js文件。并在utils.js文件中添加以下代碼,如代碼清單10-1。清單10-1創(chuàng)建Ajax異步請求對象functioncreateRequest(){

varreq=null;

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

returnreq;}異步請求對象的創(chuàng)建在第9章異步請求對象中已經(jīng)詳細(xì)的講解,有不太清楚的地方,請參閱第9章9.1節(jié)。10.4.3請求并解析XML在js文件夾中新建request.js文件,完成如下操作。第1步:給btn按鈕注冊事件處理程序給按鈕注冊事件需要在網(wǎng)頁初始化時完成,并采用自定義addEvent()函數(shù)實(shí)現(xiàn)對click事件的注冊,代碼如清單10-2所示。清單10-2給按鈕注冊單擊事件//注冊初始化函數(shù)window.onload=init;

//文檔初始化functioninit(){

varbtn=document.getElementById("btn"); addEvent(btn,'click',requestXML,false);}第2步:編寫requestXML事件處理代碼編寫10.2中注冊的requestXML函數(shù),實(shí)現(xiàn)對服務(wù)器的請求。首先,通過第2步創(chuàng)建的createRequest函數(shù)創(chuàng)建req對象。然后調(diào)用req的open方法,打開請求鏈接responseXML.jsp,并采用GET(第1個參數(shù),注意這個參數(shù)全部字母要大寫)和異步(第3個參數(shù))方式請求服務(wù)器。第三,對readystatechange事件注冊處理程序,準(zhǔn)備解析服務(wù)器發(fā)回的數(shù)據(jù)。最后,調(diào)用req的send()方法發(fā)送請求。代碼清單如10-3所示。清單10-3requestXML請求代碼functionrequestXML(){ req=createRequest(); req.open('GET','responseXML.jsp',true); req.onreadystatechange=getDetail; req.send();}第3步:解析XML在此明確兩個概念:結(jié)點(diǎn)和標(biāo)記。這兩個概念是一個事物的兩個方面,在XML文檔中就稱之為標(biāo)記,在XML對象中就稱之為結(jié)點(diǎn)。就如同在HTML文檔中,<p>稱之為p標(biāo)記,而在DOM對象中,則稱為p結(jié)點(diǎn)。如10.2.1節(jié)中的<category>就稱之為標(biāo)記,而通過getElementsByTagName(“category”)獲得的就稱之為category結(jié)點(diǎn)。根據(jù)對10.2.1節(jié)XML文件的觀察,我們可得到以下結(jié)論:(1)根標(biāo)記為<item>。(2)根標(biāo)記由若干個<category>標(biāo)記組成。(3)<category>標(biāo)記分為兩種:一種是只包含一個<name>標(biāo)記和一個<value>標(biāo)記的<category>(如圖9-1左上部分所示);另一種是包含一個<name>標(biāo)記和多個<value>標(biāo)記的<category>,它有一個特征就是包含type屬性,且其值為list(如圖10-1右上部分所示)。我們從XML中解析到數(shù)據(jù)以后要顯示在HTML文檔中,所以要把解析到的數(shù)據(jù)轉(zhuǎn)換成HTML的DOM結(jié)點(diǎn)。我們的目標(biāo)是把XML數(shù)據(jù)解析成如圖10-1的下半部分所示的HTML結(jié)構(gòu)。圖10-1XML內(nèi)容到HTML的轉(zhuǎn)換把每個<category>中的數(shù)據(jù)包含在一個p段落中,其中<name>中的數(shù)據(jù)以<strong>標(biāo)記進(jìn)行強(qiáng)調(diào)顯示,后跟<value>中的數(shù)據(jù)。如果<value>標(biāo)記有多個,則把多個<value>中的數(shù)據(jù)顯示在一個無序列表中。最后,把這個p段落標(biāo)記放置到容器div中。結(jié)合要解析的XML結(jié)構(gòu)特征和要顯示的目標(biāo)格式,可制訂如下解析策略:首先,使用XML對象(異步請求對象的responseXML就表示XML對象)的getElementsByTagName()函數(shù)獲取所有的<category>。其次,對于每個category結(jié)點(diǎn)對象,調(diào)用其getElementsByTagName()函數(shù),獲得name結(jié)點(diǎn)和value結(jié)點(diǎn)。第三,對于name結(jié)點(diǎn),通過其firstChild屬性(因?yàn)閚ame標(biāo)記只有一個文本結(jié)點(diǎn)。注意:不論文字有多長,都看作一個文本結(jié)點(diǎn))的nodeValue屬性,得到name結(jié)點(diǎn)中的數(shù)據(jù)。然后通過document對象的createElement()函數(shù)創(chuàng)建strong標(biāo)記結(jié)點(diǎn),通過createTextNode()創(chuàng)建name結(jié)點(diǎn)數(shù)據(jù)的文本結(jié)點(diǎn)對象,并通過strong結(jié)點(diǎn)的appendChild()函數(shù)將文本結(jié)點(diǎn)添加到strong標(biāo)記中。第四,對于單個<value>標(biāo)記,則取出它的數(shù)據(jù)創(chuàng)建文本結(jié)點(diǎn),并添加到段落標(biāo)記中。如果是多個<value>標(biāo)記,則把每個value中的數(shù)據(jù)放置到li結(jié)點(diǎn)中,最后添加到ul結(jié)點(diǎn)中。具體解析XML的詳細(xì)步驟和代碼①清空容器我們要把解析后的數(shù)據(jù)放置到一個id為content的div標(biāo)記中,每次添加數(shù)據(jù)之前必須把容器清空。因?yàn)?,我們采用的是添加結(jié)點(diǎn)的方式添加數(shù)據(jù)的,所以如果顯示前不清空容器,則會把每次顯示的數(shù)據(jù)疊加,造成多余的數(shù)據(jù),所以要清空容器。清空容器的代碼如下://通過id獲得容器對象varcon=document.getElementById("content"); //清空顯示容器 for(vari=con.childNodes.length;i>0;i--){ //依次移除容器的最后一個孩子結(jié)點(diǎn) con.removeChild(con.childNodes[i-1]); }②獲取XML

要獲取服務(wù)器傳回的XML數(shù)據(jù),只需要訪問異步請求對象的responseXML屬性即可,這個屬性就指向XML對象,它本身是Document類型的對象。代碼如下:varrespXML=req.responseXML;其中req是創(chuàng)建的異步請求對象。③

解析XML

首先,通過XML對象(此處為respXML)的getElementsByTagName()方法,獲得XML文檔中的所有<category>標(biāo)記,如下面代碼的注釋①。然后,通過for循環(huán)遍歷每個category結(jié)點(diǎn),如下面代碼注釋②。第三,對兩種category結(jié)點(diǎn)分別進(jìn)行處理。對于只包含一個name結(jié)點(diǎn)和一個value結(jié)點(diǎn)的,分別讀取name結(jié)點(diǎn)和value結(jié)點(diǎn)的值,然后把讀取到的值創(chuàng)建DOM結(jié)點(diǎn),插入到容器中,如下面代碼的注釋③。對于包含type屬性的category,即包含一個name結(jié)點(diǎn)和多個value結(jié)點(diǎn)的category,則先處理name結(jié)點(diǎn),然后通過category對象的getElementsByTagName()函數(shù)獲得所有的value結(jié)點(diǎn),并通過一個循環(huán)遍歷所有的value結(jié)點(diǎn),并通過value結(jié)點(diǎn)的firstChild屬性的nodeValue屬性讀取value結(jié)點(diǎn)的值,如下面代碼的注釋④。綜上所述,得到XML文檔解析的框架(偽代碼)如下。varcategories=respXML.getElementsByTagName("category"); //①for(vari=0;i<categories.length;i++){ //② //取第i個category varcategory=categories[i]; //解析name結(jié)點(diǎn)數(shù)據(jù),并生成數(shù)據(jù)的DOM結(jié)點(diǎn)的代碼//取第i個category的類型type varcategoryType=category.getAttribute("type");//分類型處理兩種不同的category if(無type屬性的category){ //③ //取得第i個category的value標(biāo)記的數(shù)據(jù) //category的value標(biāo)記數(shù)據(jù)創(chuàng)建DOM結(jié)點(diǎn) }else{ //④ //獲取category的多個value標(biāo)記的數(shù)據(jù)varvalues=category.getElementsByTagName("value"); for(varj=0;j<values.length;j++){ //取第j個value標(biāo)記的內(nèi)容 varval=values[j].firstChild.nodeValue; //生成DOM結(jié)點(diǎn)的代碼 } //生成DOM結(jié)點(diǎn)的代碼 }

}

④解析結(jié)點(diǎn)數(shù)據(jù)解析name結(jié)點(diǎn)的數(shù)據(jù):首先通過category結(jié)點(diǎn)(name結(jié)點(diǎn)的父結(jié)點(diǎn))的getElementsByTagName()函數(shù),而不整個XML文檔對象結(jié)點(diǎn)的getElementsByTagName()函數(shù)(這一點(diǎn)至關(guān)重要?。?,取得name結(jié)點(diǎn)。注意getElementsByTagName()函數(shù)返回的是一個數(shù)組,如果只取一個元素,要在后面加數(shù)組訪問運(yùn)算符[0]。然后,通過name結(jié)點(diǎn)的firstChild屬性(此屬性表示結(jié)點(diǎn)的第一個孩子結(jié)點(diǎn))的nodeValue屬性讀取name結(jié)點(diǎn)的值,代碼如下:varnameElement=category.getElementsByTagName("name")[0]; varcategoryName=nameElement.firstChild.nodeValue;解析value結(jié)點(diǎn)的數(shù)據(jù),與解析name結(jié)點(diǎn)的數(shù)據(jù)類似,只不過通過getElementsByTagName()函數(shù)查找value結(jié)點(diǎn),代碼如下:varvalueElement=category.getElementsByTagName("value")[0]; varcategoryValue=valueElement.firstChild.nodeValue;解析多個value結(jié)點(diǎn)的數(shù)據(jù):首先通過category結(jié)點(diǎn)(value結(jié)點(diǎn)的父結(jié)點(diǎn))的getElementsByTagName()函數(shù)獲取其下的所有value結(jié)點(diǎn),這里得到一個結(jié)點(diǎn)的數(shù)組。然后通過循環(huán)遍歷數(shù)組中的每個value結(jié)點(diǎn),通過其firstChild屬性的nodeValue屬性讀取其中的數(shù)據(jù),代碼如下:varvalues=category.getElementsByTagName("value"); for(varj=0;j<values.length;j++){ //取第j個value標(biāo)記的內(nèi)容 varval=values[j].firstChild.nodeValue; //生成DOM結(jié)點(diǎn)的代碼 }

⑤生成HTMLDOM結(jié)點(diǎn)上一步得到的XML數(shù)據(jù)要顯示在網(wǎng)頁上,必須通過程序創(chuàng)建DOM結(jié)點(diǎn)的辦法插入到網(wǎng)頁中。根據(jù)我們對XML文檔結(jié)構(gòu)的分析和既定的顯示格式,需要對name結(jié)點(diǎn)、value結(jié)點(diǎn)和多個value結(jié)點(diǎn)分別進(jìn)行處理。對于name結(jié)點(diǎn),我們顯示格式是放在<strong>標(biāo)記中,以強(qiáng)調(diào)的形式加以顯示,然后再把<strong>標(biāo)記添加到段落標(biāo)記<p>中。首先,通過document對象的createElement()函數(shù)創(chuàng)建段落結(jié)點(diǎn)(相當(dāng)于創(chuàng)建段落標(biāo)記<p>),代碼如下://創(chuàng)建段落標(biāo)記 varp=document.createElement('p');第二,創(chuàng)建strong結(jié)點(diǎn),代碼如下://創(chuàng)建strong標(biāo)記 varstrong=document.createElement("strong");第三,利用讀取的name結(jié)點(diǎn)的數(shù)據(jù)創(chuàng)建文本結(jié)點(diǎn)。注意,name中的數(shù)據(jù)是沒有冒號“:“的,要在創(chuàng)建文本結(jié)點(diǎn)時加上。從這一點(diǎn)可以說明,XML中沒有的數(shù)據(jù),而我們需要顯示的,可以按照要求加上的。//創(chuàng)建名稱文本結(jié)點(diǎn) varnameText=document.createTextNode(categoryName+':');第四,將生成的文本結(jié)點(diǎn)添加到strong結(jié)點(diǎn)中。 strong.appendChild(nameText);第五,將strong標(biāo)記添加到段落結(jié)點(diǎn)p中。p.appendChild(strong);對于value結(jié)點(diǎn)值的DOM對象的創(chuàng)建與name結(jié)點(diǎn)類似,在此不再贅述。下面討論多個value結(jié)點(diǎn)的數(shù)據(jù)創(chuàng)建DOM的方法。根據(jù)顯示要求,多個value值要放在一個無序列表中,也就是說,每個value結(jié)點(diǎn)值的DOM結(jié)點(diǎn)要放在li標(biāo)記中。然后再把這個li標(biāo)記放到ul標(biāo)記中。首先,創(chuàng)建ul結(jié)點(diǎn),代碼如下:varlist=document.createElement("ul");第二,獲得category結(jié)點(diǎn)的所有value結(jié)點(diǎn)。varvalues=category.getElementsByTagName("value");第三,循環(huán)遍歷獲得的values數(shù)組,逐一處理每個value結(jié)點(diǎn)。過程是:讀取value結(jié)點(diǎn)的值(方法見④解析結(jié)點(diǎn)數(shù)據(jù)),然后將該值創(chuàng)建成文本結(jié)點(diǎn),然后創(chuàng)建li結(jié)點(diǎn),將文本結(jié)點(diǎn)添加到li結(jié)點(diǎn)中,最后把li結(jié)點(diǎn)添加到創(chuàng)建的ul結(jié)點(diǎn)中,代碼如下://獲取第i個category的所有value標(biāo)記 for(varj=0;j<values.length;j++){ //取第j個value標(biāo)記的內(nèi)容 varval=values[j].firstChild.nodeValue; //創(chuàng)建文本結(jié)點(diǎn) varvalText=document.createTextNode(val); //創(chuàng)建li結(jié)點(diǎn) varli=document.createElement("li"); li.appendChild(valText); //將li結(jié)點(diǎn)添加到ul中 list.appendChild(li); }第四,將ul結(jié)點(diǎn)添加到段落標(biāo)記p中,最后把段落標(biāo)記添加到容器中,代碼如下: con.appendChild(p); con.appendChild(list);綜上所述,得到如清單10-4所示的解析XML的代碼。10.4.4服務(wù)器響應(yīng)XML數(shù)據(jù)

在項(xiàng)目WebContent目錄上右鍵單擊,選擇“New→JSPFile”,新建responseXML.jsp文件,接收客戶端發(fā)送的請求,并以XML數(shù)據(jù)進(jìn)行響應(yīng)。雖然服務(wù)器端編碼不屬于Ajax的范疇,但Ajax也不能脫離服務(wù)器端而獨(dú)立存在。所以,服務(wù)器端編碼是實(shí)用Ajax不可或缺的部分。在實(shí)際開發(fā)中,我們是將從數(shù)據(jù)庫中提取出來的數(shù)據(jù)轉(zhuǎn)換成XML格式的文檔,然后再送往客戶端,在此為了敘述和實(shí)例的簡單性,我們把XML文檔放到項(xiàng)目的files文件夾下的item.xml文件中。我們的任務(wù)是讀取item.xml中的內(nèi)容,再把讀取到的內(nèi)容送到客戶端,步驟如下。第1步:文件定位

使用application內(nèi)置對象的getRealPath()方法,獲取files目錄在磁盤上的絕對路徑,便于下一步讀取文件。代碼如下:Stringpath=application.getRealPath("files");第2步:新建JavaFile對象引用文件

只需要用Java的關(guān)鍵字new一個File對象即可,比較簡單,代碼如下:FilexmlFile=newFile(path+"/item.xml");第3步:讀取文件到緩沖區(qū)首先,創(chuàng)建指向文件的輸入流,這里的文件就是上一步中創(chuàng)建的xmlFile文件對象。代碼如下:InputStreamReaderis=newInputStreamReader(newFileInputStream(xmlFile));第二,創(chuàng)建按行讀取的BufferedReader對象。由于我們的XML文檔是以文本的形式存儲于磁盤文件中,讀取文本文件以按行讀取為佳,所以我們創(chuàng)建按行讀取的BufferedReader對象。BufferedReader對象的輸入是上一步中創(chuàng)建的InputStreamReader的對象,即is。代碼如下:BufferedReaderbr=newBufferedReader(is);第三,讀取文件內(nèi)容到緩沖區(qū)。我們把讀取到的文件先放到StringBuilder緩沖區(qū)中,最后一次性寫入客戶端。所以先創(chuàng)建StringBuilder對象。接下來調(diào)用BufferedReader對象的(這里是br)readLine()方法一次讀取一行,存放到臨時字符串str中,然后去掉str中的首尾空格添加到StringBuilder中,直到讀取到的行為null為止,讀取完成。讀取完成后關(guān)閉BufferedReader對象。代碼如下://創(chuàng)建字符串緩沖區(qū)StringBuilder對象StringBuildersb=newStringBuilder();//臨時存放讀取的行文本的字符串變量 Stringstr=null;//一次讀取一行,直到讀取到的行為null,完成文件的讀取 while((str=br.readLine())!=null){ //去掉首尾空格,添加到StringBuilder緩沖區(qū)中sb.append(str.trim()+"\n"); }//關(guān)閉BufferedReader對象 br.close();第四,把數(shù)據(jù)寫入客戶端。首先,把存放在StringBuilder對象(這里是sb)中的內(nèi)容轉(zhuǎn)換成字符串。只需要調(diào)用sb的toString()方法即可,代碼如下:Stringcontent=sb.toString();第二,設(shè)置響應(yīng)類型。

這一步最必須的,必須設(shè)置響應(yīng)格式為text/xml;charset=UTF-8。text/xml說明服務(wù)器響應(yīng)客戶端的內(nèi)容格式,這里說明響應(yīng)的XML格式的文檔。charset=UTF-8說明響應(yīng)內(nèi)容所使用的編碼方式為UTF-8。UTF-8為通用的字符編碼,一般項(xiàng)目中都采用這一編碼方式。代碼如下: response.setContentType("text/xml;charset=UTF-8");第三,將XML內(nèi)容寫入客戶端。

這一步需要借助response內(nèi)置對象的getWriter()方法獲取PrintWriter對象(java.io.PrintWriter),該對象將字符串格式的內(nèi)容寫入到客戶端。調(diào)用該對象的write()方法將響應(yīng)內(nèi)容寫入客戶端。寫入完成后,必須調(diào)用flush()方法,該方法將JSP的緩沖區(qū)清空。最后調(diào)用close()方法,這個方法至關(guān)重要,一定要寫,否則客戶端收不到服務(wù)器的數(shù)據(jù),而會一直等待!代碼如下: PrintWriterpw=response.getWriter(); pw.write(content); pw.flush(); pw.close();綜合上述代碼,得到完整的服務(wù)器端響應(yīng)XML的代碼,如代碼如清單10-5所示。10.4.5運(yùn)行結(jié)果

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論