掌握SAX
發表時間:2024-02-05 來源:明輝站整理相關軟件相關文章人氣:
[摘要]在用DOM耗費較長時間解析XML文件以后,你可能注意到在用DOM處理大型文件時其性能下降的非常厲害。這個問題是由DOM的樹結構所造成的:這種結構占用的內存較多,而且DOM必須在解析文件之前把整個文檔裝入內存。在采用DOM之后性能受到嚴重影響的情況下,你不妨考慮使用Simple API for XM...
在用DOM耗費較長時間解析XML文件以后,你可能注意到在用DOM處理大型文件時其性能下降的非常厲害。這個問題是由DOM的樹結構所造成的:這種結構占用的內存較多,而且DOM必須在解析文件之前把整個文檔裝入內存。在采用DOM之后性能受到嚴重影響的情況下,你不妨考慮使用Simple API for XML(SAX)。在這篇文章中,我們就為你介紹SAX API,同時提出若干采用不同語言實現的SAX鏈接。
SAX最初是由David Megginson采用Java語言開發的,之后SAX很快在Java開發者中流行起來。SAN項目現在負責管理其原始API的開發工作,這是一種公開的、開放源代碼軟件。不同于其他大多數XML標準的是,SAX沒有語言開發商必須遵守的標準SAX參考版本。因此,SAX的不同實現可能采用區別很大的接口。不過,所有的這些實現至少有一個特性是完全一樣的,這就是事件驅動。
事件驅動的文檔解析
在SAX解析器裝載XML文件時,它遍歷文件文檔并在其主機應用程序中產生事件(經由回調函數、指派函數或者任何可調用平臺完成這一功能)表示這一過程。這樣,編寫SAX應用程序就如同采用最現代的工具箱編寫GUI程序。
大多數SAX實現都會產生以下若干類型的事件:
在文檔的開始和結束時觸發文檔處理事件。
在文檔內每一XML元素接受解析的前后觸發元素事件。任何元數據通常都由單獨的事件交付。
在處理文檔的DTD或Schema時產生DTD或Schema事件。
錯誤事件用來通知主機應用程序解析錯誤。
顯而易見,在處理文檔時你最關心的就是元素事件了。通常,SAX解析器會向你的主機應用程序提供包含元素信息的事件參數;在最低程度下也會提供元素的名字。具體取決于你的特定實現,可以定義不同類型的元素事件代表不同類型元素的處理。例如,注釋元素(它可能包含主機應用程序的處理指令)就經常在接受處理時產生特殊的事件。
下面我們就舉個比較基本的例子。假如你把程序清單A中的XML文件裝入了SAX解析器,那么你可能會在你的主機應用程序中收到以下事件通知:
Document Start
Element Start "catalog"
Element Start "book"
Element Start "author"
Data "Adams, Lamont"
Element End "author"
Element Start "title"
Data "Lamont’s First Book"
Element End "title"
Element End "book"
Element End "catalog"
Document End
SAX對DOM
在什么情況下采用這種或者那種API并沒有確定的嚴格規則;具體情況具體分析。所有的SAX處理都在一次遍歷中完成的;因此,在解析同等大小的文檔時SAX通常會相比DOM提供更好的性能(因為DOM必須遍歷樹結構)。此外,與DOM是比,因為在給定的時間之內只需要XML文檔的一部分裝入內存,所以SAX 通常在處理更大文件時內存的利用效率也來得更高(我已經提到過,DOM在開始解析文檔之前必須把全部XML文檔裝入內存)。
然而,SAX也不是沒有缺點。SAX應用程序一般都比較長,程序中充斥著大量的if/else結構用來確定處理特定元素時所采用的運動。同樣的,處理多個XML元素之間散布的數據結構也很成問題,因為解析事件之間必須保存中間數據。最后, SAX應用程序的事件處理結構一般意味著SAX應用程序是針對特定文件結構定制構建的,而DOM應用程序則更具一般性。
從哪里獲得SAX
相當多的SAX實現都可以從網上獲得。不幸的是,它們之間稍有不同,但其大多數都提供了相應的幫助文檔。以下是一些流行的SAX實現:
當然,最“標準”的Java版本在SAX項目網站。
Microsoft XML Core Services 4.0 庫包括了采用COM的SAX解析器,對VB程序員特別有用(或開發Windows的程序員)。
支持Perl的binding of SAX 2.0。
SAX in C++ 是一套用在SAX和C++應用程序中的C++接口和封裝類。
許多編程語言,比如Python和所有的.NET語言都在其核心功能中內建支持SAX。