SAX在讀取XML流的同時去處理他們,參考下面的XML片段:





分析這個代碼片段的SAX處理器將產生以下事件:
1. Start document
2. Start element (user)
3. Characters (white space)
4. Start element (name)
5. Characters (Chris)
6. End element (name)
7. Characters (white space)
8. Start element (sex)
9. Characters (male)
10. End element (sex)
11. Characters (white space)
12. End element (user)
SAX的處理涉及以下步驟:
1. 創建一個事件處理程序;
2. 創建SAX解析器;
3. 向解析器分配事件處理程序;
4. 解析文檔,同時向事件處理程序發送每個事件。
這種基于事件的處理,應用程序可以不必解析整個文檔,可以在某個條件得到滿足時停止解析;應用程序是在讀取時檢查數據,因此不需要將數據存儲在內存中,這對于大型文檔來說是個巨大的優點,但也是由于該特點,使用SAX來更改數據或在數據流中往后移也是不可能的。
DOM由于樹狀結構在內存中是持久的,因此可以對數據和結構作出更改,還可以在樹中上下導航,使用起來要簡便的多;但由于在內存中構造樹涉及大量的開銷,創建DOM樹可能是一個緩慢的過程。
SAX和DOM也并不是互相排斥的,可以使用DOM來創建SAX事件流,也可以使用SAX來創建DOM樹,很多創建DOM樹的解析器都是使用SAX來完成這個任務的。
SAX使用
1. 創建事件處理程序
在使用SAX處理XML之前,必須創建一個事件處理程序。SAX提供了一個DefaultHandler類,可以從該類擴展。
2. 創建解析器XMLReader
要使用XML文檔做任何事情,都需要通過解析器讀取其中的信息,可以通過SAXParserFactory和SAXParser來創建解析器。
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
XMLReader reader = parser.getXMLReader();
3. 驗證與非驗證解析器
解析器分為兩種類型:非驗證和驗證。驗證解析器根據已定義的語法檢查XML文檔的內容和結構,通過驗證的文檔被認為是有效的文檔;非驗證解析器則忽略此驗證操作。可通過設置validating屬性關閉SAXParserFactory創建的解析器的驗證特性:
Factory.setValidating(false);
4. 設置內容處理程序
解析器將它的時間發送到一個ContentHandler,DefaultHandler擴展了ContentHandler。可通過XMLReader的setContentHandler()方法來指定。
5. 解析InputSource
解析xml文檔需要一個InputSource,它包裝了要處理的數據,XMLReader的parse()方法接受包裝了文件的InputSource,同時將每個事件發送給ContentHandler。
InputSource source = new InputSource(“test.xml”);
Reader.parse(source);
6. 設置ErrorHandler
可以通過ErrorHandler來處理解析數據所遇到的錯誤,DefaultHandler也繼承了ErrorHandler,可通過XMLReader的setErrorHandler()方法來指定。
常用的事件
1. startDocument()
使用該事件來開始文檔,但不做任何事情,該事件會拋出一個SAXException。
2. startElement()
元素開始的事件。解析器將每個元素的信息傳遞給該事件,包括:
· 限定名稱或qName
名稱空間信息(若存在)和元素的實際名陳的組合,如存在名稱空間,則包括冒號(:)。
· 名稱空間URI
表示名稱空間的URI。
· 本地名稱localName
元素的實際名稱。如果元素沒有名稱空間信息,解析器可能無法確定qName的哪個部分是localName。
· 屬性Attributes
元素屬性的對象集合。
3. endElement()
元素結束的事件。
4.Characters()
獲得元素后,通過該事件來檢索實際的數據。方法簽名是:
public void characters(char[] ch, int start, int length) throws SAXException
ch字符數組包括整個文檔,可通過起始和長度信息來獲取當前元素的字符。
5. ignorableWhitespace()
解析器不是在Characters()中將文檔的空白字符床地給內容處理程序的,而是在ignorableWhitespace()事件中傳遞的。
6. endDocument()
該事件用于處理文檔解析完成。
7. ErrorHandler
ErrorHandler也有預定義用于處理錯誤的事件,包括:warning, error, fatalError。
8. XMLFilters
由于SAX在讀取數據時分析數據,可以通過XMLFilters在分析數據之前對數據進行更改。