XML的DOM和SAX解析方式
昨天抽取并解析了一大批從微信鉤子收取到的小程序消息,它們都是用很復雜的XML表示的。平常不是很接觸XML,本文就隨便說說XML的兩種解析方式。
DOM解析方式
DOM即文檔對象模型(document object model)。根據W3C的描述,DOM是一套用于HTML和XML文檔的標準接口,它定義了文檔的邏輯結構,以及訪問或操作文檔的方式。
DOM Parser會將文檔解析為包含元素、屬性和文本的樹形結構(類似抽象語法樹,但帶有細節)。舉個例子,對于如下的XML文檔:
<?xml version="1.0" encoding="utf-8"?>
<wikimedia>
<projects>
<project name="Wikipedia" launch="2001-01-05">
<editions>
<edition language="English">en.wikipedia.org</edition>
<edition language="German">de.wikipedia.org</edition>
<edition language="French">fr.wikipedia.org</edition>
<edition language="Spanish">es.wikipedia.org</edition>
</editions>
</project>
<project name="Wiktionary" launch="2002-12-12">
<editions>
<edition language="English">en.wiktionary.org</edition>
<edition language="French">fr.wiktionary.org</edition>
</editions>
</project>
</projects>
</wikimedia>
DOM解析后形成的樹形結構如下圖所示(為了節省空間,把文本域都省略了)。

用DOM解析方式處理XML文檔時,要求文檔必須全部加載進內存,才能形成完整的樹形結構,所以文檔越大,消耗的內存也就越多。如果文檔大小比可用內存還大,那么DOM解析方式就無能為力了。但它允許用戶可以在任何時候定位和讀寫文檔中的任意一部分數據,也可以任意創建和刪除元素,稱為“隨機訪問”特性(當然與平時所說的線性數組的隨機訪問特性不太像一回事)。
SAX解析方式
SAX是Simple API for XML的縮寫。與DOM不同,它是一套以流式、事件驅動的方式解析XML文檔的標準接口,并且是完全開放的。不過SAX不像DOM一樣有W3C制定的標準,現在一般認為Java的SAX實現(org.xml.sax)是事實上的標準。
SAX Parser總是逐行順序掃描文檔,當遇到文檔的開始/結束、元素的開始/結束、處理指令、文本、注釋等等情況時,會回調相應的事件處理方法。以org.xml.sax.ContentHandler處理器為例,上一節的維基百科XML文本會按如下流程解析:
文檔開始 -> startDocument()
wikimedia元素開始 -> startElement()
projects元素開始 -> startElement()
project元素開始 -> startElement() [屬性 -> name="Wikipedia" launch="2001-01-05"]
editions元素開始 -> startElement()
edition元素開始 -> startElement() [屬性 -> language="English"]
文本en.wikipedia.org -> characters()
edition元素結束 -> endElement()
......
editions元素結束 -> endElement()
project元素結束 -> endElement()
......
wikimedia元素結束 -> endElement()
文檔結束 -> endDocument()
由此可見,SAX解析與DOM解析最大的不同在于,SAX解析不需要將文檔整體載入內存,而是讀入一些、解析一些。當遇到元素結束時,就可以釋放掉該元素范圍內的所有數據,內存占用會顯著降低,基本只與元素的嵌套深度有關系,解析速度也要優于DOM方式。所以就算文檔大小比可用內存還大,用SAX解析也不用擔心。
但是SAX只能順序解析文檔,完全不能隨機訪問。并且它對文檔的全貌是無感知的,所以也就不支持修改。如果對這兩點有硬性需求,就只能老老實實用DOM解析了。
dom4j
dom4j是Java環境下一個相當強大的XML框架(我這次用的就是它)。雖然名字叫dom4j,但它同時支持DOM和SAX兩種解析方式,并且提供了更高級、易用的特性,如迭代器、XPath支持、XSLT等。dom4j的介紹和文檔都可以在它的官網https://dom4j.github.io/找到,這里就不再廢話了。
XML尚能飯否?
XML和JSON哪個更好?也許很多人都會下意識地回答JSON,但這個問題實際上無法一概而論。因為XML是一種語言,而JSON是一種數據格式,只不過XML也可以用來表達數據而已。JSON雖然輕量易用,但XML也擁有JSON不具有的高級特性。看官可以參考知乎上的這個問題獲得更多信息(請忽略問題本身的傾向性)。
今天缺覺,民那晚安。
智能推薦
SAX方式解析XML文件
SAX,全稱Simple API for XML,是一種以事件驅動的 XML API,SAX 與 DOM 不同的是它邊掃描邊解析, 自頂向下依次解析, 由于邊掃描邊解析, 所以它解析 XML 具有速度快, 占用內存少的優點。 SAX解析XML的步驟 創建SAXParserFactory對象 通過SAXParserFactory對象創建SAXParser對象 創建DefaultHandler的子類 ...
Android XML DOM解析SAX解析
聲明:內容大部分參考自網友博客。個人只是做了小小的總結 我個人覺得可以用MVC模式去看待解析xml文件的實現: 下面是具體實現: 首先編寫一個xml的數據文件存放在res/raw文件目錄下: 1.編寫模型代碼: 2.視圖編輯: 3.控制器代碼: 下面是具體實現: 首先編寫一個xml的數據文件存放在res/raw文件目錄下: 1.編寫模型代碼: 2.視圖編輯: 3.控制器代碼:...
XML的DOM解析方式
XML解析流程 核心包 javax.xml.parsers 包中的DocumentBuilderFactory用于創建DOM模式的解析器對象 , DocumentBuilderFactory是一個抽象工廠類,它不能直接實例化,但該類提供了一個newInstance方法 ,這個方法會根據本地平臺默認安裝的解析器,自動創建一個工廠的對象并返回。 解析流程 調用 DocumentBuilderFacto...
XML學習筆記(一)之DOM及SAX方式解析XML原理
1.XML XML 指可擴展標記語言(eXtensible Markup Language)。XML 被設計用來傳輸和存儲數據。 (1)XML 文檔形成了一種樹結構,它從"根部"開始,然后擴展到"枝葉"。 示例: &nb...
Java中xml解析 SAX、PULL、DOM
目錄 一,什么是XML: 二,XML的解析 一,什么是XML: 定義:XML指的是可擴展標記語言,主要用來傳輸和存儲數據。 XML主要語法規則: XML標簽需要用戶自定義 XML標簽使用時要關閉<標簽名> </標簽名>成對存在 XML標簽對區分大小寫 XML標簽必須正確的嵌套 XML文檔有且只有一個根元素 XML的屬性值要加引號 XML中的空格換行符等會被當做...
猜你喜歡
Android之PULL、SAX、DOM解析XML
背景:解析天氣預報的xml文件,在模擬器顯示 解析前準備 layout目錄下weather.xml 需要解析的文件:raw目錄下的weather1.xml WeatherBean.java MainActivity.java將weather1.xml解析到的信息映射到布局weather.xml中 PULL解析 PULL解析器的運行方式和SAX類似,都是基于事件的模式。不同的是,在PULL解析過程中...
XML解析___使用Dom or使用Sax
xml解析方式分為兩種,dom和sax dom:(Document Object Model,即對文檔對象模型)是W3C組織推薦的處理XML的一種方式 Sax:(Simple API for XML)不是官方標準,但它是xml社區事實上的標準,幾乎所有的xml解析器都支持它。 XML解析開發包 Jaxp、Jdom、dom4J 使用DOM解析XML介紹 DOM...
xml文件--SAX方式解析xml文件
SAX介紹 SAX的全稱是Simple APIs for XML,也即XML簡單應用程序接口。 與DOM不同,SAX提供的訪問模式是一種順序模式,這是一種快速讀寫XML數據的方式。 當使用SAX分析器對XML文檔進行分析時,會觸發一系列事件,并**相應的事件處理函數,應用程序通過這些事件處理函數實現對XML文檔的訪問,因而SAX接口也被稱作事件驅動接口。 局限性: 1. SAX...
SAX解析和xml約束
一、SAX解析 1.特點 SAX解析:讀一點,取一點,節省內存空間。一旦遇到開始標簽觸發之后,及時從內存中將開始節點從內存中釋放點。 2.三要素 3.DOM解析和SAX解析的區別 原理:前者,讀一點,取一點,節省內存空間。一旦遇到開始標簽觸發之后,及時從內存中將開始節點從內存中釋放點。 后者,一次性加載整個xml文件,如果xml...