天天看點

用SAX2解析xml

sax2是The Simple API for xml的意思,是一種解析xml的方式。解析xml主要有二種方式,一個是dom,比較常用,解析完成以後再記憶體形成一個結構,另外一個方式就是一種事件解析方式,就是在解析到一定的内容抛出事件,繼續向後處理,xml讀取完成,也就解析完成,xml的内容并不存入記憶體。

Java API for XML Processing (JAXP) 對于xml解析進行了一層抽象,為了防止代碼中混淆特定廠家的代碼,jaxp對于xml的解析進行了抽象,他本身隻是一個抽象層,不具有解析xml的能力,但是可以有第三方獨立的機構進行代碼的開發,這樣的解析器很多,比如Sun的Crimson 還有apache的Xerces 等等

對于javax.xml.parsers下的類進行一個說明

DocumentBuilder

定義 API, 使其從 XML 文檔擷取 DOM 文檔執行個體。使用此類,應用程式員可以從 XML 擷取一個

Document

此類的執行個體可以從

DocumentBuilderFactory.newDocumentBuilder()

方法擷取。擷取此類的執行個體之後,将可以從各種輸入源解析 XML。這些輸入源為 InputStreams、Files、URL 和 SAX InputSources。

注意,此類重用了 SAX API 中的一些類。這并不要求底層 DOM 實作的實作者使用 SAX 解析器将 XML 文檔解析為

Document

。它僅要求該實作使用這些現有的 API 與應用程式交流。

DocumentBuilderFactory

定義工廠 API,使應用程式能夠從 XML 文檔擷取生成 DOM 對象樹的解析器

SAXParserFactory

定義工廠 API,使應用程式能夠配置和擷取基于 SAX 的解析器以解析 XML 文檔。

SAXParser

定義包裝

XMLReader

實作類的 API。在 JAXP 1.0 中,此類包裝

Parser

接口,但是此接口由

XMLReader

取代。為了便于過渡,此類繼續支援相同的名稱和接口,并支援新方法。 此類的執行個體可以從

SAXParserFactory.newSAXParser()

方法獲得。擷取此類的執行個體之後,将可以從各種輸入源解析 XML。這些輸入源為 InputStream、File、URL 和 SAX InputSource。

此靜态方法根據系統屬性設定建立新的工廠執行個體,如果未定義屬性,則使用平台預設值。

控制建立哪個工廠實作的系統屬性命名為

"javax.xml.parsers.SAXParserFactory"

。此屬性命名一個類,該類為此抽象類的具體子類。如果未定義屬性,将使用預設的平台。

由于内容由基礎解析器解析,是以将調用給定

HandlerBase

DefaultHandler

的方法。

包裝基礎實作的此類的實作程式可以考慮使用

ParserAdapter

類,進而使其 SAX1 實作最初在此修訂類下工作

其中包含了二個異常類

ParserConfigurationException

訓示一個嚴重的配置錯誤。

FactoryConfigurationError

當解析器工廠的配置存在問題時抛出該異常。當找不到系統屬性中指定的解析器工廠的類時,或者該類不能被執行個體化時,通常抛出此錯誤。

剛才說到jaxp裡面都是一個抽象層,他都是依靠第三方的解析器進行的xml的解析,那麼修改配置也成為一種必然需求,其實更改 JAXP 工廠類使用的解析器很容易。更改解析器實際上意味着更改解析器工廠,因為所有

SAXParser

DocumentBuilder

執行個體都來自這些工廠。工廠确定加載哪個解析器,是以必須更改工廠。要更改

SAXParserFactory

接口的實作,請設定 Java 系統特性

javax.xml.parsers.SAXParserFactory

。如果未定義此特性,則傳回預設實作(不管開發商指定哪個解析器)。同一規則适用于所使用的

DocumentBuilderFactory

實作。在這種情況下,将會查詢

javax.xml.parsers.DocumentBuilderFactory

系統特性。

sax的處理代碼風格主要如下二種:

1.           

            // Get SAX Parser Factory

            SAXParserFactory factory = SAXParserFactory.newInstance();

            // Turn on validation, and turn off namespaces

            factory.setValidating(true);

            factory.setNamespaceAware(false);

            SAXParser parser = factory.newSAXParser();

            parser.parse(new File(args[0]), new MyHandler());

2.org.xml.sax.XMLReader parser = saxParser.getXMLReader();

// Use the underlying parser

parser.setContentHandler(myContentHandlerInstance);

parser.setErrorHandler(myErrorHandlerInstance);

parser.parse(new org.xml.sax.InputSource(args[0]));