隨筆-128  評論-55  文章-5  trackbacks-0
           摘要XML作為過去十年中出現的最流行的技術之一,得到了廣泛的應用,而其中XML解析技術是XML應用的關鍵。本文介紹了XML解析技術的研究動向,分析和比較了4XML解析技術的優劣,并歸納總結了應用系統設計中選取合適的XML解析技術的原則。

          1  引言

          XML(eXtensible Markup Language,可擴展標記語言)是由World Wide Web聯盟(W3C)定義的元語言,即一種關于語言的語言。XML的設計源于SGML (Standard Generalized Markup Language,標淮通用標記語言) ,是SGML的子集,其目的是為了促進Internet上結構化文檔的交換。簡單的說,XML是一組規則和準則的集合,用于以無格式文本來描述結構化數據[1]1996W3C聯盟就開始從事XML的標準化工作,并于1998210發布了XML1.0

          XML的出現給分布式計算領域帶來了重大影響,其力量源于它的數據獨立性[1]XML是純數據描述,與編程語言、操作系統或傳輸協議無關,從而將數據從以代碼為中心的基礎結構所產生的約束中解放出來,讓數據能夠在Web上更自由的流通。

          然而XML本身只是以純文本對數據進行編碼的一種格式,要想利用XML,或者說利用XML文件中所編碼的數據,必須先將數據從純文本中解析出來,因此,必須有一個能夠識別XML文檔中信息的解析器,用來解釋XML文檔并提取其中的數據。然而,根據數據提取的不同需求,又存在著多種解析方式,不同的解析方式有著各自的優缺點和適用環境。選擇合適的XML解析技術能夠有效提升應用系統的整體性能,因此,了解和區分各種不同的XML解析技術就顯得尤為重要。

          2  XML解析技術分析

          所有的XML處理都從解析開始,無論是使用XSLTJava語言,第一步都是要讀入XML文件,解碼結構和檢索信息等等,這就是解析,即把代表XML文檔的一個無結構的字符序列轉換為滿足XML語法的結構化組件的過程。

          2.1 XML解析技術的分類

          根據從XML中獲取數據的簡易性,性能和最終所得到的數據模型的不同,XML解析技術大致可分為以下四類:

          1)       面向文檔的流式解析;

          2)       面向文檔的對象式解析;

          3)       面向文檔的指針式解析;

          4)       面向應用的對象式解析;

          這四類解析技術分別處于不同的抽象層次,適用于不同的應用場景,有著各自的優缺點。針對具體的應用需求,選擇合適的解析技術,往往能夠減少內存消耗,縮短處理時間,更方便地獲取數據,提高應用系統的整體性能。

          2.2 面向文檔的流式解析技術

          流式解析是一種基于事件的解析過程,解析器順序讀取XML文檔,產生一個對應的事件流,并向事件處理程序發送所捕獲的各種事件,如元素開始和元素結束等,而事件處理程序則通過不同的方法處理這些事件。

          流式解析是將XML文檔作為一個數據流來處理,因此,它具有類似于流媒體的優點,能夠立即開始讀取數據,而不是等待所有的數據被處理。而且,由于應用程序只是在讀取數據時檢查數據,不需要將整個文檔一次加載到內存中,使得在處理大型文檔時具有較好的時間和空間上的效率。然而效率的代價是易用性的降低,流式解析編程較為復雜,程序員需要負責更多的操作。并且由于應用程序沒有以任何方式存儲數據,所以使得更改數據或在數據流中往后移是不可能的。再加上它的單遍解析特性,意味著它也不支持隨機訪問。

          流式解析又分為兩種解析方式:推式解析(SAX)和拉式解析(StAX)。這兩種方式的主要區別在于是由解析器還是應用程序控制讀循環(讀入文件的循環)

          2.2.1 推式解析(SAX解析技術)

          SAX(Simple API for XML)解析技術就是一種推式解析,在這種解析方式中,解析器控制著讀循環,在文檔結束之前控制權不會返回給應用程序[3]。解析器通過回調的方式進行數據處理。

          SAX提供了一個用于處理XML的,基于事件驅動的簡單API。它的設計開始于XML-DEV郵件列表成員間的討論,他們開發出的第一個接口草案SAX1.019981月發布,其后在20005月發布了SAX2.0,目前最新版本是20044月發布的SAX2.0.2SAX沒有經過官方的標準機構認可,它不由W3C聯盟或其它任何官方機構維護(現在,SAXDavid Megginson維護) [4],但它被廣泛使用并視為XML社區事實上的標準。SAX最初是為Java而定義的,但也可以用于PythonPerlC++等其它語言。

          SAX是基于事件驅動的,即SAX解析器在讀取XML文檔的過程中生成一個事件流,并且對于每個事件通過回調事件處理程序中相應的方法來進行處理。比如元素開始和結束標記,元素內容,實體,語法分析錯誤等事件。針對下面的簡單XML文檔,所產生的事件如圖1所示,注意針對元素內的空格或回車也會生成一個文本事件。

          1 SAX解析器生成的事件

          SAX中的核心事件處理程序是一個實現了ContentHandler接口的類。此接口中定義了處理與XML文檔本身關聯的事件的方法,如 startDocumentendDocumentstartElementendElementCharacters

          SAX解析技術具有所有流式解析技術的優點和缺點,但是由于在整個解析過程中,解析器掌握著控制權直到文檔結束,應用程序很難在獲得所需的部分數據后停止解析過程(可以通過拋出異常的方式終止解析過程,但較為復雜,而且終止后也無法繼續解析過程),因此產生了由應用程序掌握控制權的拉式解析方式。

          2.2.2 拉式解析(StAX解析技術)

          StAX(Streaming API for XML)解析技術是一種拉式解析,在這種解析方式中,應用程序控制著讀循環。循環中,應用程序負責反復調用解析器獲得下一個事件,直到文檔結束。通過保留解析過程的控制權,可以簡化調用代碼來準確地處理它預期的內容,并且可隨時停止解析。此外,由于該方式沒有基于處理程序回調,應用程序也不需要像SAX中那樣模擬解析器的狀態。

          StAX針對同樣的XML文檔所獲得事件類型和SAX基本相同,但是StAX包含了兩套處理XMLAPI:基于指針的API和基于迭代器的API,分別提供了不同程度的抽象[5]

          基于指針的API簡單的返回事件,此時事件用數值形式來表示。這是一種低層API,沒有提供底層XML結構的抽象,所有的狀態信息直接從流讀取器獲得,不需要創建額外的對象。從而節約內存,擁有較高的效率。

          而較為高級的基于迭代器的API則以對象方式返回事件,每個事件對象都封裝了它所表示的特定XML結構固有的信息,因此可直接利用其方法獲得屬于該結構的信息,但也需要額外的對象創建開銷。相對于基于指針的API,基于迭代器的API具有更多的面向對象特征,因此更便于應用于模塊化的體系結構。

          StAX也是用Java定義的,其StAX1.020043月發布,并且成為了JSR-173 規范,最新版本為20066月發布的StAX1.2StAX作為用Java語言處理XML的最新標準,比早期出現的XPP (Xml Pull Parser)拉式解析器功能更為強大,也得到了更為廣泛的應用。

          2.3 面向文檔的對象式解析技術

          由于流式解析方式固有的無法更改數據和不支持隨機訪問特性,尤其是沒有對XML文檔的結構建模,使得應用程序很難對XML文檔進行搜索、修改、添加和刪除等操作。為了解決這些問題,產生了面向文檔的對象式解析技術--DOM

          DOM(Document Object Model)是用與平臺和語言無關的方式對XML文檔進行建模的官方W3C標準[6],其目標是提供一個可以通用于各種程序語言、操作系統和應用程序的接口。DOM最初被當作Web瀏覽器識別和處理頁面元素的方式,即在W3C介入之前的功能,稱為“DOM Level 0W3C199810月提出了“DOM Level 1建議,支持XML1.0HTML處理。隨后于200011月提出了“DOM Level 2建議,對Level 1進行了擴展,支持XML1.0、命名空間和CSS,也支持用戶接口和樹形操作事件,并且添加了DOM樹形操作功能。最新的“DOM Level 3建議于20036月提出,在level 2的基礎上添加了對DTDXML模式和XPath的支持[1]

          DOM作為一種對象式解析技術,定義了層次化對象模型來表示XML文檔。即為XML語法中的每個概念(如元素,屬性,實體,文檔等)定義對應的類,而解析器在讀入XML文檔的時候,會建立XML語法和類之間的一一映射。實際上,DOM的層次化對象模型是一個樹形結構,它將一個XML文檔看作一棵節點樹,每個節點代表一個XML文檔中的元素。DOM的基本節點對象有5[1](1)Document對象:是樹的最高節點,也是對整個文檔操作的入口;(2)ElementAttr對象:對文檔中元素和元素屬性的映射;(3)Text對象:作為ElementAttr對象的子節點,代表了元素或屬性的文本內容;(4)NodeList對象:對節點按指定的方式進行遍歷。

          例如對于2.2.1中的XML文檔,其對應的DOM節點樹如下圖所示(注意元素內的空格或回車也會被當作文本對象)

          2 DOM節點樹 (矩形框表示元素節點,橢圓表示文本節點)

          利用DOM在內存中建立的完整的XML文檔的樹形結構,開發人員就可以方便的對XML文檔進行一系列操作,如遍歷、增加、刪除、修改文檔內容等,且具有良好的導航能力。同時DOM所具有的對象特性也非常便于面向對象編程。然而,由于DOM在使用數據前需要完整的遍歷XML文檔,在內存中構建樹形結構表示,因此需要消耗大量的內存,尤其是對于大型文檔,性能下降的很快。而且必須一次解析整個XML文檔,不可能只做部分解析,當只關注XML文檔的小部分數據時,效率很低。(Axis2項目中的Axiom對象模型實現了對XML文檔的部分解析,可構建不完整的節點樹,但實現較為復雜)

          由于DOM是與語言無關的,當DOM接口進入指定語言的數據結構時,會產生不必要的復雜性,無法利用語言本身的優勢。因此出現了許多與DOM類似的針對特定語言的對象模型。如JDOM就是針對Java的特定文檔對象模型,JDOM使用具體類而不使用接口,簡化了API,并在API中大量使用了Java集合類。DOM4J則是JDOM的一種智能分支,它提供了對XPathXML Schema的支持,并且通過DOM4J API和標準DOM接口使其具有并行訪問功能[5]。它們都屬于面向文檔的對象式解析技術。

          2.4 面向文檔的指針式解析技術

          前面提到的面向文檔的流式解析效率較高,但易用性差,而對象式解析易用性強,卻效率較低,這兩種方式似乎處于兩個極端。其效率問題主要在于兩種方式都是提取解析模式,即解析時,提取一部分源文件,一般來說是一個字符串,然后在內存中進行解析構建。這種解析模式注定了需要大量的創建和銷毀對象,而且還存在更新效率問題,在DOM(SAX并不支持更新),每一次改動都需要將DOM模型重新完整的解析成XML字符串,原文件并沒有被利用,即DOM并不支持增量更新。為了解決這些問題,提出了一種較新穎的指針式解析技術,即VTD-XML

          VTD-XML是一種無提取的XML解析方法,它較好的解決了DOM占用內存過大的缺點,并且還提供了快速的解析與遍歷、對XPath的支持和增量更新等特性。VTD-XML是一個開源項目,目前有JavaC兩種平臺支持,第一個版本是20046月發布的VTD-XML0.5,其VTD- XML1.0版本于200510月發布,最新的版本為200710月發布的VTD-XML2.2

          VTD(Virtual Token Descriptor,虛擬令牌描述符)是一個64bits長度的數值類型,記錄了每個元素的起始位置,長度,深度以及令牌的類型等信息,如圖3所示。64bits固定長度使得可以用數組這種高效的結構來組織VTD,大幅提高性能。VTD是實現無提取解析的關鍵,它類似于XML文檔中元素的指針,通過它可以快速定位到某個元素。

          3 VTD記錄的比特層格式

          令牌開始偏移量(即相對于XML文檔頭部的距離)30 bits,也就是說它能解析的最大文件是1G。令牌長度為20 bits,即一個令牌的最大長度是1M。令牌類型4bits,說明支持16種詞匯類型。

          為了實現無提取這個目的,VTD-XML將原XML文件原封不動的以二進制的方式讀進內存,不做解碼,然后在這個比特數組上解析每個元素的位置并把一些信息,如XML令牌的開始偏移量、長度、深度和令牌類型,記錄下來,保存為VTD數組,之后的遍歷操作便可在VTD數組上進行。如果需要提取XML內容,就查找VTD數組,利用VTD記錄中的位置等信息在原始比特數組上進行解碼并返回字符串。

          而且VTD-XML還可以高效的實現增量更新,例如,如果想在一個大型XML文檔中找出一個節點元素并刪除它,那么只需要找到這個元素的VTD,將這個VTDVTD數組中刪除,然后再利用所有的VTD寫出到另一個二進制數組中就可以了,因為刪除的VTD標明了要刪除的元素的位置,所以在新寫入的二進制數組中就不會出現這段元素了。用VTD寫入新的二進制數組的過程實際上就是一個二進制數組的拷貝過程,其效率是非常高的[2]

          由此可見,VTD很好的解決了前兩種解析方式的缺點,通過其巧妙的設計使得在解析XML文檔時內存占用少,效率高,并且還能夠實現XML文檔的快速解析與遍歷、提供對XPath的支持。VTD的出現是XML解析技術的一大進步,會對XML解析技術的發展產生巨大影響。

          2.5 面向應用的對象式解析技術

          前面所談到的三種解析技術都是從XML的角度來處理文檔和建立模型,這對于主要關心文檔的XML結構的應用程序來說是適用的,但是有很多應用程序僅僅將XML作為數據交換的媒介,它們更關心的是文檔數據本身。此時,面向應用的對象式解析(或稱為XML數據綁定)可以使應用程序在很大程度上忽略XML文檔的實際結構,而直接使用文檔的數據內容。

          數據綁定是指將數據從一些存儲媒介(XML文檔、文本文件和數據庫)中取出,并通過應用程序表示這些數據的過程,即把數據綁定到虛擬機能夠理解并且可以操作的某種內存中的結構[9]。數據綁定并不是一個新鮮的概念,其在關系數據庫上早已得到了廣泛的應用,如Hibernate就是針對數據庫的輕量級數據綁定框架。而針對XML數據綁定的Castor框架在2000年就已經出現,目前已經涌現出了許多類似的框架,如JBindJAXBJiBXQuickZeus等。

          其中JAXB(Java Architecture for XML Binding)是一個處于不斷發展中的應用于Java平臺的數據綁定框架,提供了一套在XML文檔和Java對象之間自動映射的API,符合JSR31--XML數據綁定規范(XML Data Binding Specification)。該項目始于19998月,由Java Community Process開發,其1.0版本于200210月發布,目前最新版本為2007917發布的JAXB2.1.5

          如圖4,顯示了數據綁定在數據庫和XML文檔中的應用。

          4 數據綁定

          在數據綁定中有三個重要概念[9]

          l        編組(Marshalling):把內存中的數據轉換到存儲介質中的過程。在JavaXML環境中,編組就是把一些Java對象轉化為一個(或多個)XML文檔。其核心就在于把Java中的面向對象結構轉化成適用于XML的扁平結構。

          l        解組(Unmarshalling):把數據從存儲媒介轉換到內存中的過程。JavaXML環境中,即將XML文檔解組到Java虛擬機中,其復雜性在于從數據到Java代碼變量的映射。

          l        映射(Mapping):用于編組和解組的一套規則。

          初看起來XML數據綁定和面向文檔的對象式解析較為相似,都在內存中構建文檔表示,同時內部表示和標準的XML文檔之間可以互相轉換。但兩者之間的不同在于文檔模型盡可能接近的保存XML的文檔結構,而數據綁定只關心應用程序使用的文檔數據[7]。如圖5所示,同一個XML文檔的文檔模型和數據綁定模型是完全不同的。

          5 文檔模型和數據綁定模型比較

          如果應用程序使用文檔模型方法,那么獲得所需要的數據就必須在節點樹中根據父子節點關系進行遍歷。而使用數據綁定方法,只需進行正常的Java編程,訪問數據更加容易,速度也比文檔模型快得多。而且,XML數據綁定并不只是簡化編程,由于它把許多文檔細節抽象出來,所以數據綁定所需的內存通常少于文檔模型所需的內存,如上圖中,文檔模型方法使用了10個單獨的對象,而數據綁定才使用2個。此外,由于要構建的對象少得多,所以為XML文檔構建數據綁定表示還可能更快[7]

          XML數據綁定中最為核心的是怎樣由XML文檔生成Java對象。目前有兩種方式:映射綁定方式和代碼生成方式[8]。在映射綁定方式中,構建自己的Java類,并向綁定框架指定這些類如何與XML文檔相關聯。如框架CastorQuick就支持這種方式。而代碼生成方式則根據XML文檔結構(DTDSchema形式的文法)自動構建相應的Java類,如JAXBCastorJBind提供了根據XML文檔的Schema描述生成Java代碼,QuickZeus可根據DTD描述生成Java代碼。

          代碼生成方式所構造的類可以包括完整的數據類型信息,還能夠對所構造的類進行驗證。但該方式使得程序代碼和文檔結構之間緊密耦合,如果文檔結構發生變化,就需要重新生成代碼。而映射綁定方式則具有更大的靈活性,其使用自己構建的對象類將數據和行為組合在一起,通過修改映射定義(而不是改變應用程序代碼)來處理XML文檔結構中的微小變化,可以在一定程度上解除對象類與實際XML文檔之間的耦合[8]。其缺點在于需要編寫較為復雜的映射文件。

          Author: orangelizq
          email: orangelizq@163.com

          歡迎大家訪問我的個人網站 萌萌的IT人
          posted on 2009-07-19 15:25 桔子汁 閱讀(17108) 評論(9)  編輯  收藏 所屬分類: Web Service

          評論:
          # re: XML解析技術研究(一) 2009-07-20 10:07 | dennis
          這篇文章發表于
          《計算機工程與科學》2009年02期

          確認是你原創嗎?  回復  更多評論
            
          # re: XML解析技術研究(一) 2009-07-20 10:11 | dennis
          XML解析技術研究
          馮進;丁博;史殿習;張矚熹;許凱
            XML解析技術是XML語言被廣泛應用的前提和基礎,計算平臺和XML應用特征的變化不斷推動著該技術的發展。本文分析了XML解析技術存在的挑戰,在對現有XML解析技術進行分類的基礎上詳細比較和分析了各類技術的特點及應用場景,指出了XML解析技術未來的研究趨勢。
          【作者單位】:國防科技大學計算機學院;總后后勤科學研究所;國防科技大學理學院
          【關鍵詞】:XML;XML解析;XML應用
          【基金】:國家863計劃資助項目(2006AA01Z198)
          【分類號】:TP312.2
          【DOI】:CNKI:SUN:JSJK.0.2009-02-037

            回復  更多評論
            
          # re: XML解析技術研究(一) 2009-07-20 10:11 | dennis
          作者有5位,做人要厚道  回復  更多評論
            
          # re: XML解析技術研究(一) 2009-07-21 09:13 | 桔子汁
          你說的那篇文章《XML解析技術研究》馮進;丁博;史殿習;張矚熹;許凱。我下載看過了,如果你仔細看看的話,會發現除了題名恰好一樣外,內容根本不一樣,而且我文章中提出的分類方式,上文中也根本未提。不可否認我文中的大部分內容為來自互聯網的資料,但我都在參考文獻中注明了。我會把那篇文章的截圖附上,以供參考!  回復  更多評論
            
          # re: XML解析技術研究(一) 2009-07-21 09:31 | 桔子汁
          上述文章《XML解析技術研究》馮進;丁博;史殿習;張矚熹;許凱。我已通過截圖的方式發布到另一篇文章中,請大家對照參考學習。在此,發布未經過文章原作者同意,請諒解。  回復  更多評論
            
          # re: XML解析技術研究(一) 2009-07-21 10:04 | dennis
          @桔子汁
          嗯,我對比了下,那是我不厚道了,確實并非完全一樣。我武斷了,因為看了太多轉載不注明的文章了。
          如果確實是你原創,那么我要說這篇文章非常棒。請原諒我的武斷。我會向管理員說明。  回復  更多評論
            
          # re: XML解析技術研究(一)[未登錄] 2010-02-03 09:08 | roger
          感謝orangelizq  回復  更多評論
            
          # re: XML解析技術研究(一)[未登錄] 2013-06-07 14:30 | chchpd
          文章不錯,收藏了。  回復  更多評論
            
          # re: XML解析技術研究(一)[未登錄] 2015-07-21 13:02 | 小林
          我有份XML,我需要解開明碼,用什么格式轉換都可以,有償價格。你看下能做不,報個價格我。我QQ;200879086 麻煩看見跟我聯系  回復  更多評論
            
          主站蜘蛛池模板: 广州市| 清远市| 仪征市| 马尔康县| 尚志市| 衡阳县| 舒城县| 田林县| 贵溪市| 义马市| 嘉兴市| 四平市| 油尖旺区| 金沙县| 乾安县| 荔浦县| 柏乡县| 辉县市| 天全县| 元朗区| 吴堡县| 喀什市| 东城区| 汝州市| 沅江市| 富宁县| 正安县| 神农架林区| 扬中市| 客服| 阜康市| 镇安县| 镇原县| 新郑市| 青浦区| 麻江县| 闵行区| 丰台区| 丽水市| 奈曼旗| 梅州市|