SAX

出自 华夏文化百科
前往: 導覽搜尋

基本簡介

SAX最初是由DavidMegginson採用Java語言開發的,之後SAX很快在Java開發者中流行起來。SAN項目現在負責管理其原始API的開發工作,這是一種公開的、開放原始碼軟體。不同於其他大多數XML標準的是,SAX沒有語言開發商必須遵守的標準SAX參考版本。因此,SAX的不同實現可能採用區別很大的接口。不過,所有的這些實現至少有一個特性是完全一樣的,這就是事件驅動。

相當多的SAX實現都可以從網上獲得。不幸的是,它們之間稍有不同,但其大多數都提供了相應的幫助文檔。以下是一些流行的SAX實現:最「標準」的Java版本在SAX項目網站


MicrosoftXMLCoreServices4.0庫包括了採用COM的SAX解析器,對VB程式設計師特別有用(或開發Windows的程式設計師)。


支持Perl的bindingofSAX2.0。


SAXinC++是一套用在SAX和C++應用程式中的C++接口和封裝類。許多程式語言,比如Python和所有的.NET語言都在其核心功能中內建支持SAX。


文檔解析

在SAX解析器裝載XML文件時,它遍歷文件文檔並在其主機應用程式中產生事件(經由回調函數指派函數或者任何可調用平台完成這一功能)表示這一過程。這樣,編寫SAX應用程式就如同採用最現代的工具箱編寫GUI程序。

大多數SAX實現都會產生以下若干類型的事件:


在文檔的開始和結束時觸發文檔處理事件。在文檔內每一XML元素接受解析的前後觸發元素事件。任何元數據通常都由單獨的事件交付。在處理文檔的DTD或Schema時產生DTD或Schema事件。錯誤事件用來通知主機應用程式解析錯誤。


顯而易見,在處理文檔時你最關心的就是元素事件了。通常,SAX解析器會向你的主機應用程式提供包含元素信息的事件參數;在最低程度下也會提供元素的名字。具體取決於你的特定實現,可以定義不同類型的元素事件代表不同類型元素的處理。例如,注釋元素(它可能包含主機應用程式的處理指令)就經常在接受處理時產生特殊的事件。


事件通知

假如把程序清單A中的XML文件裝入了SAX解析器,那麼你可能會在你的主機應用程式中收到以下事件通知:

DocumentStartElementStart「catalog」ElementStart「book」ElementStart「author」Data「Adams,Lamont」ElementEnd「author」ElementStart「title」Data「Lamont'sFirstBook」ElementEnd「title」ElementEnd「book」ElementEnd「catalog」DocumentEnd

SAX對DOM,在什麼情況下採用這種或者那種API並沒有確定的嚴格規則;具體情況具體分析。所有的SAX處理都在一次遍歷中完成的;因此,在解析同等大小的文檔時SAX通常會相比DOM提供更好的性能(因為DOM必須遍歷樹結構)。此外,與DOM是比,因為在給定的時間之內只需要XML文檔的一部分裝入內存,所以SAX通常在處理更大文件時內存的利用效率也來得更高(DOM在開始解析文檔之前必須把全部XML文檔裝入內存)。


SAX也不是沒有缺點。SAX應用程式一般都比較長,程序中充斥著大量的if/else結構用來確定處理特定元素時所採用的運動。同樣的,處理多個XML元素之間散布的數據結構也很成問題,因為解析事件之間必須保存中間數據。最後,SAX應用程式的事件處理結構一般意味著SAX應用程式是針對特定文件結構定製構建的,而DOM應用程式則更具一般性。


解析實例

在Java中使用XML是一個內容相當豐富的主題;可以使用多個API,而且許多API使得使用XML簡單得如同從文本文檔讀取行。基於樹的API(如DOM)展現了一個內存中的XML結構,該結構對於GUI和編輯器來說是最理想的,基於流的API(如SAX)對於只需要獲取文檔數據的高性能應用程式來說很重要。在本技巧文章系列中,將從基礎知識開始一步步地教您如何在Java中使用XML。同時,您將學習許多甚至連眾多專業人士都不知道的訣竅,所以即使您已經具有一些XML經驗

從SAX(SimpleAPIforXML)開始。雖然該API或許是Java和XMLAPI中最難以掌握的,但它可能也是功能最強的API。另外,大多數其它API實現(象DOM解析器、JDOM和dom4j等)都部分地基於SAX解析器。對於用XML和Java語言所做的每一件事情,理解SAX會給予您一個良好的開端。特別在本篇技巧文章中,將討論如何獲取SAX解析器實例以及如何對該解析器設置一些基本功能和屬性。


獲取SAX解析器實例


//ObtainaninstanceofanXMLReaderimplementationfromasystempropertyXMLReaderparser=org.xml.sax.helpers.XMLReaderFactory.createXMLReader();


通過使用這個方法,您需要將系統屬性org.xml.sax.driver設置成想要裝入的解析器的類名。這是特定於供應商的類;對於Xerces,它應該是org.apache.xerces.parsers.SAXParser。用-D開關將這個參數指定給Java編譯器:


java-Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParsersome.sample.Class


當然,您要確保指定的類存在並在類路徑上。


功能設置

一旦有了解析器實例,就需要配置它。請注意,這與設置解析器來處理XML中的錯誤、內容或結構不同;相反,配置是實際告訴解析器如何操作的過程。您可以打開驗證、關閉名稱空間檢查及擴展實體。這些行為完全獨立於特定的XML文檔,因此涉及與新解析器實例的交互。

註:對於那些過於急燥的人來說(知道您不是這樣的),當然會處理內容、錯誤處理及類似的東西。然而,這些主題將在未來的技巧文章中討論,所以您還得複查。眼下,只關注配置、功能和屬性。


可以用兩種方法配置解析器:功能和屬性。功能包括打開或關閉特定功能,比如驗證。屬性包括設置解析器所使用的特定項的值,如用來驗證所有文檔的模式位置。將先討論功能,然後在下一節研究屬性


功能是通過解析器上名為setFeature()的方法設置的,這一點並不奇怪。


設置SAX解析器的功能


//ObtainaninstanceofanXMLReaderimplementationfromasystempropertyXMLReaderparser=org.xml.sax.helpers.XMLReaderFactory.createXMLReader();StringfeatureName="somefeatureURI";booleanfeatureOn=true;try{parser.setFeature(featureName,featureOn);}catch(SAXNotRecognizedExceptione){System.err.println("Unknownfeaturespecified:"+e.getMessage());}catch(SAXNotSupportedExceptione){System.err.println("Unsupportedfeaturespecified:"+e.getMessage());}catch(SAXExceptione){System.err.println("Errorinsettingfeature:"+e.getMessage());}


這相當清楚,不需要說明;關鍵是知道可用於SAX解析器的常見功能。每個功能均由一個特定的URI標識。可以從SAX網站在線獲得這些URI的完整列表。