陳春艷
(廣州市市政職業(yè)學校經濟與管理部,廣東廣州510500)
XML(可擴展標記語言)因為其輕便簡潔、結構嚴謹、跨平臺支持等多種特性,現(xiàn)已經廣泛地應用于各種應用程序的數(shù)據(jù)存儲、數(shù)據(jù)交換當中。B/S結構的應用程序都普遍使用XML語言傳輸數(shù)據(jù)。特別在對Web Service進行調用時,其返回結果必然為XML格式的內容。
可是XML的設計目的是用來傳送及攜帶數(shù)據(jù)信息,不是用來表現(xiàn)或展示數(shù)據(jù),因此單純的XML并沒有規(guī)定如何顯示數(shù)據(jù)。雖然可以在定義XML文件的時候,使用CSS、XSLT等方式規(guī)定XML內容的布局與呈現(xiàn);但在B/S結構的Web應用中,特別是Web Service的調用返回時,由于考慮到網絡傳送的問題,往往都只是純粹的XML文本;這就只能依靠客戶端腳本呈現(xiàn)文本內容。
在AJAX應用模型中,通常利用XMLHttpRequest對象發(fā)送服務器請求,若服務器端返回的數(shù)據(jù)是XML格式,則通過XMLHttpRequest對象的ResponseXML屬性獲得返回數(shù)據(jù)。在主流的瀏覽器中,所獲得的ResponseXML內容存在一定的差異,而且不同瀏覽器所定義的XML DOM也各有千秋。這樣使得客戶端編程的程序員難以只用一種方法直接將XML的數(shù)據(jù)呈現(xiàn)在不同的瀏覽器中,這大大增加了Web應用開發(fā)的難度和開發(fā)時間。
微軟的IE在個人電腦用戶瀏覽器的使用份額中占有比較大的優(yōu)勢,達到60.65%,其次是使用Mozilla內核的FireFox瀏覽器,達到24.52%(注:來自Net Applications公司2010年3月的調查數(shù)據(jù))。兩大主流瀏覽器之間,對于服務器端返回ResponseXML對象從內容到操作對象都有很顯著的區(qū)別。
IE瀏覽器所得到的ResponseXML對象與實際的XML內容比較一致,而且可以通過名為xml的屬性得到包括XML聲明在內的全部內容。可通過代碼如alert(XHR.ResponseXML.xml)訪問全部的XML內容。
假設現(xiàn)有ResponseXML對象得到的內容部分節(jié)點如下所示:

在訪問XML的數(shù)據(jù)內容時,通常有兩種方法。第一種方法是遍歷法。因為XML文檔的內容結構是一棵有著眾多節(jié)點的樹,因此可以通過逐層遍歷的方式,從父元素節(jié)點一直訪問到最終的葉子元素節(jié)點,通過葉子元素節(jié)點的test屬性得到其文本節(jié)點的內容??赏ㄟ^以下代碼得到第一個class的title元素的文本內容。

如果利用節(jié)點訪問的方式,可以通過nextSibling屬性返回當前節(jié)點的下一個兄弟節(jié)點。由于IE瀏覽在構造XML內容節(jié)點的時候,某父節(jié)點下的所有子節(jié)點是利用一個數(shù)組存儲的。因此可以利用節(jié)點的索引得到需要的子節(jié)點內容??赏ㄟ^以下代碼可跳過第一個class節(jié)點得到第二個class的內容。

第二種方法是按照元素名稱直接訪問法。通過getElementById的方法,可以得到全部元素名相同的節(jié)點。該方法所返回的是一個節(jié)點數(shù)組,通過循環(huán)遍歷數(shù)組中的元素則可以得到全部信息內容??赏ㄟ^以下代碼得到兩個title元素的內容。

在Firefox瀏覽器中,服務器應答的responseXML內容與實際的XML內容有較大的差異。在Firefox中,不會去除元素之間的空格符號,因此每一個元素節(jié)點的第一個子節(jié)點不是元素類型,而是文本類型。這樣就導致內容信息在Firefox中節(jié)點的索引編號與IE并不一樣。如圖1所示,F(xiàn)irefox中每個class節(jié)點前都有一個空的文本節(jié)點,子節(jié)點總數(shù)為4而不是2。

圖1 Firefox中的節(jié)點信息
此外,在Firefox中并不存在一些IE特有的方便訪問XML內容的方法。如上文提及的xml和text屬性。因此,上面在IE中可以成功訪問XML內容的代碼全部失效,程序員不得不為Firefox的用戶重新寫一遍讀取的方法。以下代碼演示讀取第二個class元素的title內容在Firefox中的修正。

W3C組織是對網絡標準制定的一個非贏利組織,W3C定義了包括XML和DOM在內的許多互聯(lián)網應用的協(xié)議規(guī)范。其中DOM(文檔對象模型)為HTML、XML等數(shù)據(jù)載體和信息載體在內存中的處理提供了一種基本的對象模型。標準中提供連接到文件的結構、格式、事件等各方面的內容。由于不依賴于任何程序設計語言和網頁描述語言,它為有效處理HTML和XML數(shù)據(jù)提供了一種標準的、獨立的接口。
不同的瀏覽器廠商在設計瀏覽器所支持的DOM時會做出一些修改。這樣就導致了不同的瀏覽器之間對XML操作會存在不同的屬性和方法。
在W3C協(xié)議中,規(guī)范定義了XML DOM的一些操作內容。其中比較常用且大多數(shù)瀏覽器都支持的屬性有:attributes——返回元素的屬性集合;childNodes——返回元素的子節(jié)點的節(jié)點數(shù)組;firstChild——返回元素的首個子節(jié)點;nextSibling——返回元素之后緊跟的節(jié)點;parentN-ode——返回元素的父節(jié)點;previousSibling——返回元素之前緊隨的節(jié)點;nodeValue——返回當前節(jié)點的內容值(非文本節(jié)點無效)。
比較常用且大多數(shù)瀏覽器都支持的訪問XML的方法有:getElementsByTagName()——找到具有指定標簽名的子孫元素;getAttribute()——返回屬性的值;getAttributeNode()——以Attribute對象返回屬性節(jié)點。
如果每一次讀取XML的信息都要先判斷瀏覽器的類型,然后再使用不同的方法得到相應的信息,對于程序員來說是一件痛苦的事情。若利用各個瀏覽器都支持的XML DOM屬性和方法,將訪問元素節(jié)點的方法重新封裝,通過這種方法可以減輕程序員的負擔。
先判斷當前的瀏覽器是IE內核還是Mozilla內核,并用一個全局變量記錄當前瀏覽器類型。關鍵代碼如下所示:

定義一個函數(shù)getNodeValue(node,tagname),參數(shù)node是元素節(jié)點,tagname是標記的名稱。該函數(shù)將根據(jù)不同的瀏覽器類型,在node的子節(jié)點中找出標記名稱為tagname的元素節(jié)點的值,并將其返回。關鍵代碼如下:


當我們需要訪問第二個class節(jié)點的title內容時,就可以簡單用一個方法實現(xiàn)。

以上代碼均在IE7+和Firefox3.5+測試通過。這樣,客戶端程序員就可以忽略瀏覽器的復雜性,專注于數(shù)據(jù)的顯示和布局等其它方面的設計。
在RIA應用越來越頻繁的今天,客戶端編程的作用越來越大,而Javascript作為客戶端使用率最高的腳本也越來越強大,但腳本又要依賴于瀏覽器的支持;基于種種的理由,不同瀏覽器之間對腳本的支持不可能完全統(tǒng)一。一方面為了支持更多的客戶端平臺,另一方面減少客戶端編程人員的重復工作,這就需要將不同瀏覽器之間共同支持的方法進行提取,重新整合封裝,以便在客戶端編程的時候可以更快捷調用。
[1]吳潔.XML應用教程(第二版)[M].北京:清華大學出版社,2007.
[2]高怡新.XML基礎教程[M].北京:人民郵電出版社,2009.
[3]基思(英).JavaScript DOM編程藝術[M].北京:人民郵電出版社,2007.
[4]左偉明.完全掌握XML——基礎概念、核心技術與典型案例[M].北京:人民郵電出版社,2009.