1. 程式人生 > >Android解析和建立XML之學習筆記------SAX

Android解析和建立XML之學習筆記------SAX

Android解析XML的三種方式:DOM,SAM,PULL


1、DOM解析時需要將XML檔案的所有內容以文件樹的方式存放在記憶體中,所以記憶體的消耗比較大,特別是對於 執行的移動裝置來說,因為裝置資源有限,所以一般

建議採用SAX或者PULL來解析XML檔案。不過,如果XML檔案的內容比較小,採用這種方式也是可行的


2、SAX(Simple API for XML) 是基於事件驅動,邊載入邊解析。當然Android的事件機制是基於回撥函式的,在讀取到其他節點與內容的時候也會回撥一個事件。


3、PULL解析XML 的方式與SAX解析XML的方式一樣,它也是基於事件驅動的。


首先來學習一下SAX解析:


SAX解析的過程涉及到事件,有事件源和事件處理器。在SAX介面中,事件源是org.xml.sax包下的XMLR

eader,它通過parser()方法來解析XML文件,它通過parser()方法來解析XML文件,併產生事件。事件處理器是org.xml.sax包中的ContentHandler/DTDHandler、ErrorHandler,以及EntityResolver這四個介面。



介面 ContentHandler

這是一個大多數 SAX 應用程式實現的主要介面:如果需要通知應用程式基本解析事件,則它將實現此介面並且使用

setContentHandler 方法,向 SAX 解析器註冊一個例項。解析器將使用該例項報告與基本文件相關的事件,如啟動和終止元素與字元資料。

在此介面中的事件順序非常重要,它本身可映象文件中資訊的順序。例如,在 startElement 事件與相應的 endElement 事件之間,元素的所有內容(字元資料、處理指令和/ 或子元素)都將以一定順序出現。

此介面與現在不推薦使用的 SAX 1.0 DocumentHandler 介面相似,但它增加了對名稱空間和報告跳過的實體(在非驗證的 XML 處理器中)的支援。

實現者應該注意,在 java.net 包中還有一個 ContentHandler

 類;這意味著以下實現方法可能並非明智之舉

	 import java.net.*;
	 import org.xml.sax.*;
 

實際上,不管怎樣 "import ...*" 通常標誌不簡潔的程式設計,因此,使用者應該將此作為一種功能而不是錯誤。



介面 ErrorHandler


如果 SAX 應用程式需要實現自定義的錯誤處理,則它必須實現此介面,然後使用 setErrorHandler 方法向 XML 閱讀器註冊一個例項。然後解析器將通過此介面報告所有的錯誤和警告。

警告:如果應用程式 註冊 ErrorHandler,則將不報告 XML 解析錯誤,除了對嚴重的錯誤將丟擲 SAXParseException外。為了檢測有效性錯誤,必須註冊用 error() 呼叫處理某些事情的 ErrorHandler。

對於 XML 處理錯誤,SAX 驅動器必須優先於丟擲異常使用此介面:需要應用程式來決定是否對不同型別的錯誤和警告丟擲異常。但是要注意,不要求解析器在呼叫 fatalError 之後繼續報告另外的錯誤。換句話說,SAX 驅動器類可以在報告任何 fatalError 之後丟擲異常。另外,解析器可以對非 XML 錯誤丟擲適當的異常。例如,XMLReader.parse() 將對訪問實體或文件的錯誤丟擲 IOException。


方法摘要
 void error(SAXParseException exception) 
          接收可恢復的錯誤的通知。
 void fatalError(SAXParseException exception) 
          接收不可恢復的錯誤的通知。
 void warning(SAXParseException exception) 
          接收警告的通知。

介面 DTDHandler

如果 SAX 應用程式需要關於註釋和未解析的實體的資訊,則該應用程式實現此介面並使用 SAX 解析器的 setDTDHandler 方法向該解析器註冊一個例項。解析器使用該例項嚮應用程式報告註釋和未解析的實體宣告。

注意,此介面僅包括 XML 推薦標準需要 處理器報告的 DTD 事件:註釋和未解析的實體宣告。

SAX 解析器可按任何順序報告這些事件,而不管宣告註釋和未解析的實體時所採用的順序;但是,必須在文件處理程式的 startDocument 事件之後,在第一個 startElement 事件之前報告所有的 DTD 事件。(如果使用 LexicalHandler,則這些事件也必須在 endDTD 事件之前報告。)

需要依靠應用程式來儲存資訊以備將來之用(可能用雜湊表或物件樹)。如果應用程式遇到了 "NOTATION"、"ENTITY" 或 "ENTITIES" 型別的屬性,則可以使用它通過此介面獲取的資訊來查詢與該屬性值對應的實體和/ 或註釋。


介面 EntityResolver

如果 SAX 應用程式需要實現自定義處理外部實體,則必須實現此介面並使用 setEntityResolver 方法向 SAX 驅動器註冊一個例項。

然後 XML 閱讀器將允許應用程式在包含外部實體之前擷取任何外部實體(包括外部 DTD 子集和外部引數實體,如果有)。

許多 SAX 應用程式不需要實現此介面,但對於從資料庫或其他特定的輸入源中構建 XML 文件的應用程式,或者對於使用 URI 型別(而不是 URL )的應用程式,這特別有用。


基本實現思路:


1、建立SAXParserFactory 物件

2、根據SAXParserFactory.newSAXParser()方法返回一個SAXParser解析器

3、根據SAXParser解析器獲取事件源物件XMLReader

4、例項化一個DefaultHandler物件

5、連線事件源物件物件XMLReader到事件處理類DefaultHandler中

6、呼叫XMLReader的parse方法從輸入源中獲取的XML資料

7、通過DefaultHandler返回需要的資料集合

(當前要實現是將要解析的xml檔案放到專案的assess目錄下,raw,編譯的時候會打包進去)

XML檔案的引用方式如下; getResources().openRawResource9(R.raw.link);
不過在匯入xml檔案的時候出現了亂碼問題,

到編輯工具中,轉過和自己專案一樣的語言即可再重新匯入