陳春艷
(廣州市市政職業(yè)學(xué)校經(jīng)濟(jì)與管理部,廣東廣州510500)
XML(可擴(kuò)展標(biāo)記語言)因為其輕便簡潔、結(jié)構(gòu)嚴(yán)謹(jǐn)、跨平臺支持等多種特性,現(xiàn)已經(jīng)廣泛地應(yīng)用于各種應(yīng)用程序的數(shù)據(jù)存儲、數(shù)據(jù)交換當(dāng)中。B/S結(jié)構(gòu)的應(yīng)用程序都普遍使用XML語言傳輸數(shù)據(jù)。特別在對Web Service進(jìn)行調(diào)用時,其返回結(jié)果必然為XML格式的內(nèi)容。
可是XML的設(shè)計目的是用來傳送及攜帶數(shù)據(jù)信息,不是用來表現(xiàn)或展示數(shù)據(jù),因此單純的XML并沒有規(guī)定如何顯示數(shù)據(jù)。雖然可以在定義XML文件的時候,使用CSS、XSLT等方式規(guī)定XML內(nèi)容的布局與呈現(xiàn);但在B/S結(jié)構(gòu)的Web應(yīng)用中,特別是Web Service的調(diào)用返回時,由于考慮到網(wǎng)絡(luò)傳送的問題,往往都只是純粹的XML文本;這就只能依靠客戶端腳本呈現(xiàn)文本內(nèi)容。
在AJAX應(yīng)用模型中,通常利用XMLHttpRequest對象發(fā)送服務(wù)器請求,若服務(wù)器端返回的數(shù)據(jù)是XML格式,則通過XMLHttpRequest對象的ResponseXML屬性獲得返回數(shù)據(jù)。在主流的瀏覽器中,所獲得的ResponseXML內(nèi)容存在一定的差異,而且不同瀏覽器所定義的XML DOM也各有千秋。這樣使得客戶端編程的程序員難以只用一種方法直接將XML的數(shù)據(jù)呈現(xiàn)在不同的瀏覽器中,這大大增加了Web應(yīng)用開發(fā)的難度和開發(fā)時間。
微軟的IE在個人電腦用戶瀏覽器的使用份額中占有比較大的優(yōu)勢,達(dá)到60.65%,其次是使用Mozilla內(nèi)核的FireFox瀏覽器,達(dá)到24.52%(注:來自Net Applications公司2010年3月的調(diào)查數(shù)據(jù))。兩大主流瀏覽器之間,對于服務(wù)器端返回ResponseXML對象從內(nèi)容到操作對象都有很顯著的區(qū)別。
IE瀏覽器所得到的ResponseXML對象與實際的XML內(nèi)容比較一致,而且可以通過名為xml的屬性得到包括XML聲明在內(nèi)的全部內(nèi)容。可通過代碼如alert(XHR.ResponseXML.xml)訪問全部的XML內(nèi)容。
假設(shè)現(xiàn)有ResponseXML對象得到的內(nèi)容部分節(jié)點如下所示:
在訪問XML的數(shù)據(jù)內(nèi)容時,通常有兩種方法。第一種方法是遍歷法。因為XML文檔的內(nèi)容結(jié)構(gòu)是一棵有著眾多節(jié)點的樹,因此可以通過逐層遍歷的方式,從父元素節(jié)點一直訪問到最終的葉子元素節(jié)點,通過葉子元素節(jié)點的test屬性得到其文本節(jié)點的內(nèi)容。可通過以下代碼得到第一個class的title元素的文本內(nèi)容。
如果利用節(jié)點訪問的方式,可以通過nextSibling屬性返回當(dāng)前節(jié)點的下一個兄弟節(jié)點。由于IE瀏覽在構(gòu)造XML內(nèi)容節(jié)點的時候,某父節(jié)點下的所有子節(jié)點是利用一個數(shù)組存儲的。因此可以利用節(jié)點的索引得到需要的子節(jié)點內(nèi)容??赏ㄟ^以下代碼可跳過第一個class節(jié)點得到第二個class的內(nèi)容。
第二種方法是按照元素名稱直接訪問法。通過getElementById的方法,可以得到全部元素名相同的節(jié)點。該方法所返回的是一個節(jié)點數(shù)組,通過循環(huán)遍歷數(shù)組中的元素則可以得到全部信息內(nèi)容。可通過以下代碼得到兩個title元素的內(nèi)容。
在Firefox瀏覽器中,服務(wù)器應(yīng)答的responseXML內(nèi)容與實際的XML內(nèi)容有較大的差異。在Firefox中,不會去除元素之間的空格符號,因此每一個元素節(jié)點的第一個子節(jié)點不是元素類型,而是文本類型。這樣就導(dǎo)致內(nèi)容信息在Firefox中節(jié)點的索引編號與IE并不一樣。如圖1所示,F(xiàn)irefox中每個class節(jié)點前都有一個空的文本節(jié)點,子節(jié)點總數(shù)為4而不是2。
圖1 Firefox中的節(jié)點信息
此外,在Firefox中并不存在一些IE特有的方便訪問XML內(nèi)容的方法。如上文提及的xml和text屬性。因此,上面在IE中可以成功訪問XML內(nèi)容的代碼全部失效,程序員不得不為Firefox的用戶重新寫一遍讀取的方法。以下代碼演示讀取第二個class元素的title內(nèi)容在Firefox中的修正。
W3C組織是對網(wǎng)絡(luò)標(biāo)準(zhǔn)制定的一個非贏利組織,W3C定義了包括XML和DOM在內(nèi)的許多互聯(lián)網(wǎng)應(yīng)用的協(xié)議規(guī)范。其中DOM(文檔對象模型)為HTML、XML等數(shù)據(jù)載體和信息載體在內(nèi)存中的處理提供了一種基本的對象模型。標(biāo)準(zhǔn)中提供連接到文件的結(jié)構(gòu)、格式、事件等各方面的內(nèi)容。由于不依賴于任何程序設(shè)計語言和網(wǎng)頁描述語言,它為有效處理HTML和XML數(shù)據(jù)提供了一種標(biāo)準(zhǔn)的、獨立的接口。
不同的瀏覽器廠商在設(shè)計瀏覽器所支持的DOM時會做出一些修改。這樣就導(dǎo)致了不同的瀏覽器之間對XML操作會存在不同的屬性和方法。
在W3C協(xié)議中,規(guī)范定義了XML DOM的一些操作內(nèi)容。其中比較常用且大多數(shù)瀏覽器都支持的屬性有:attributes——返回元素的屬性集合;childNodes——返回元素的子節(jié)點的節(jié)點數(shù)組;firstChild——返回元素的首個子節(jié)點;nextSibling——返回元素之后緊跟的節(jié)點;parentN-ode——返回元素的父節(jié)點;previousSibling——返回元素之前緊隨的節(jié)點;nodeValue——返回當(dāng)前節(jié)點的內(nèi)容值(非文本節(jié)點無效)。
比較常用且大多數(shù)瀏覽器都支持的訪問XML的方法有:getElementsByTagName()——找到具有指定標(biāo)簽名的子孫元素;getAttribute()——返回屬性的值;getAttributeNode()——以Attribute對象返回屬性節(jié)點。
如果每一次讀取XML的信息都要先判斷瀏覽器的類型,然后再使用不同的方法得到相應(yīng)的信息,對于程序員來說是一件痛苦的事情。若利用各個瀏覽器都支持的XML DOM屬性和方法,將訪問元素節(jié)點的方法重新封裝,通過這種方法可以減輕程序員的負(fù)擔(dān)。
先判斷當(dāng)前的瀏覽器是IE內(nèi)核還是Mozilla內(nèi)核,并用一個全局變量記錄當(dāng)前瀏覽器類型。關(guān)鍵代碼如下所示:
定義一個函數(shù)getNodeValue(node,tagname),參數(shù)node是元素節(jié)點,tagname是標(biāo)記的名稱。該函數(shù)將根據(jù)不同的瀏覽器類型,在node的子節(jié)點中找出標(biāo)記名稱為tagname的元素節(jié)點的值,并將其返回。關(guān)鍵代碼如下:
當(dāng)我們需要訪問第二個class節(jié)點的title內(nèi)容時,就可以簡單用一個方法實現(xiàn)。
以上代碼均在IE7+和Firefox3.5+測試通過。這樣,客戶端程序員就可以忽略瀏覽器的復(fù)雜性,專注于數(shù)據(jù)的顯示和布局等其它方面的設(shè)計。
在RIA應(yīng)用越來越頻繁的今天,客戶端編程的作用越來越大,而Javascript作為客戶端使用率最高的腳本也越來越強大,但腳本又要依賴于瀏覽器的支持;基于種種的理由,不同瀏覽器之間對腳本的支持不可能完全統(tǒng)一。一方面為了支持更多的客戶端平臺,另一方面減少客戶端編程人員的重復(fù)工作,這就需要將不同瀏覽器之間共同支持的方法進(jìn)行提取,重新整合封裝,以便在客戶端編程的時候可以更快捷調(diào)用。
[1]吳潔.XML應(yīng)用教程(第二版)[M].北京:清華大學(xué)出版社,2007.
[2]高怡新.XML基礎(chǔ)教程[M].北京:人民郵電出版社,2009.
[3]基思(英).JavaScript DOM編程藝術(shù)[M].北京:人民郵電出版社,2007.
[4]左偉明.完全掌握XML——基礎(chǔ)概念、核心技術(shù)與典型案例[M].北京:人民郵電出版社,2009.