淺談Java Xml底層解析方式

編程語言 XML Java JSON Java團長 2017-05-18

XML 使用DTD(document type definition)文檔類型來標記數據和定義數據,格式統一且跨平臺和語言,已成為業界公認的標準。

目前 XML 描述數據龍頭老大的地位漸漸受到 Json 威脅。經手項目中,模塊/系統之間交互數據方式有 XML 也有 Json,說不上孰好孰壞。

XML 規整/有業界標準/很容易和其他外部的系統進行交互,Json 簡單/靈活/佔帶寬比小。

仁者見仁智者見智,項目推進中描述數據方式需要根據具體場景拿捏。

這篇文章主要描述目前Java中比較主流的 XML 解析底層方式,給需要這方面項目實踐的同學一些參考。

淺談Java Xml底層解析方式

sax/satx/dom 由國外開源社區或組織貢獻,Sun 重新組織起名 JAXP 自JDK 1.6 起陸續將他們添加進去。

xmlpull 在 JDK 中沒有看到它的身影,如果需要使用它,你需要添加額外的類庫。

jdom/dom4j/xstream... 是基於這些底層解析方式重新組織封裝的開源類庫,提供簡介的 API,有機會再寫一篇博客描述。

dom4j 是基於 JAXP 解析方式,性能優異、功能強大、極易使用的優秀開源類庫。

jdom 如果你細看內部代碼,其實也是基於 JAXP 但具體包結構被重新組織, API 大量使用了 Collections 類,在性能上被 dm4j 壓了好幾個檔次。

實例 Demo 中需要解析的 xml 文件如下,中規中矩不簡單,也不復雜,示例業務場景都能將節點的值解析出來,組成業務實體對象。

淺談Java Xml底層解析方式

淺談Java Xml底層解析方式

1. 基於樹或基於對象模型

官方 W3C 標準,以層次結構組織的節點或信息片斷的集合。允許在樹中尋找特定信息,分析該結構通常需要加載整個文檔和構造層次結構。

最早的一種解析模型,加載整個文檔意味著在大文件 XMl 會遇到性能瓶頸。

dom 解析代碼示例:

淺談Java Xml底層解析方式

dom 解析方式有個最大的優點可以在任何時候在樹中上下導航,獲取和操作任意部分的數據。

2. 流事件分析中推模型

靠事件驅動的模型,當它每發現一個節點就引發一個事件,需要編寫這些事件的處理程序。

這樣的做法很麻煩,而且不靈活,主流的分析方式有 xmlpull 和 JAXP 中的 sax。

xmlpull demo (引入 xmlpull.jar xpp3_min.jar]):

淺談Java Xml底層解析方式

淺談Java Xml底層解析方式

xmlpull 為接口層,xpp3_min 為實現層,其實可以引入另外自帶接口層 xpp3 版本。

淺談Java Xml底層解析方式

sax demo:

淺談Java Xml底層解析方式

sax 解析時還需要單獨編寫時間響應 Handler ,和集合排序時實現的Comparator 類似。

淺談Java Xml底層解析方式

淺談Java Xml底層解析方式

淺談Java Xml底層解析方式

推模式不需要等待所有數據都被處理,分析就能立即開始;

只在讀取數據時檢查數據,不需要保存在內存中;

可以在某個條件得到滿足時停止解析,不必解析整個文檔;

效率和性能較高,能解析大於系統內存的文檔;

當然缺點也很突出例如需要自己負責TAG的處理邏輯(例如維護父/子關係等),使用麻煩;

單向導航,很難同時訪問同一文檔的不同部分數據,不支持 XPath;

3. 流事件分析中的拉模型

在遍歷文檔時,把感興趣的部分從讀取器中拉出,不需要引發事件,允許我們選擇性地處理節點;

大大提高了靈活性,以及整體效率,拉模式中比較常見 stax,stax 提供了兩套 API 共使用。

stax demo(基於光標的方式解析XML):

淺談Java Xml底層解析方式

淺談Java Xml底層解析方式

stax demo(基於迭代方式解析XML):

淺談Java Xml底層解析方式

基於指針的 stax API,這種方式儘管效率高,但沒有提供 XML 結構的抽象,因此是一種低層 API。

stax 基於迭代器的 API 是一種面向對象的方式,這也是它與基於指針的 API 的最大區別。

基於迭代器的 API 只需要確定解析事件的類型,然後利用其方法獲得屬於該事件對象的信息。

通過將事件轉變為對象,讓應用程序可以用面向對象的方式處理,有利於模塊化和不同組件之間的代碼重用。

Ok,這篇博客對 java 底層解析 xml 方式做了點總結。其實在實際項目中,上述幾種方式解析 xml 編寫起來都很費事。

都會引入封裝起來的穩定開源庫,如 dom4j/jdom/xstream.....,這些類庫屏蔽了底層複雜的部分,呈現給我們簡潔明瞭的 API;

但如果公司業務複雜程度已經遠遠超出了開源類庫的提供的範疇,不妨自己依賴底層解析技術自己造輪子。

學習Java的同學注意了!!!

學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入Java學習交流群495273252,我們一起學Java!

相關推薦

推薦中...