SAXP解析XML的筆記

來源:互聯網
上載者:User

SAXP使用streaming讀取xml,基於事件觸發和回呼函數處理xml內容,佔用記憶體小,速度快,適用於1)僅僅讀取但是不改變xml內容 2)只處理內容一次,類似於在xml中尋找相關內容。

建立Factory

解析xml過程。首先需要建立factory,factory是用來建立parser的,包含一些建立parser的屬性。

SAXParserFactory spfactory = SAXParserFactory.newInstance(); // 得到一個執行個體
spfactory.setSchema(schema);// setSchema會使用schema產生一個validator來對被處理想xml先進性驗證,然後再發到handler去處理
spfactory.setValidating(false);// 是否驗證xml檔案,這個驗證是DTD驗證,預設為false
spfactory.setNamespaceAware(false);// 這個對於handler處理是有影響的,預設是false。如果是true,則parser會首先處理xml的prefix,找到與之對應的namespace,然後作為參數傳給handler。否則namspace就是空。spfactory.setXIncludeAware(false);//是否要處理xml中的XInclude節點,預設是false

還有一個可擴充的方法叫做setFeatures。顧名思義,就是定製由這個factory產生的parser的功能。

比如下面這行代碼:

saxfac.setFeature("http://xml.org/sax/features/namespace-prefixes", true);

當setNamespaceAware=true的時候,handler預設將得不到xmlns這些namespace相關的屬性。這個在大多數情況下有道理,因為namespace已經被parser解析好了,handler已經知道每個節點的namespace了。但是如果還是需要完整的attribute,就比較抓狂了——debug可以看到但是實際上已經被濾掉了。這時候需要設定了這個feature之後才能得到。

建立parser

設定好相應的屬性之後,就可以使用這個factory的執行個體建立parser了。

SAXParser saxParser = spfactory.newSAXParser();// 根據factory的設定,建立一個saxpparser

有了parser,可以設定不同的handler來處理xml。使用parser.getXMLReader()得到一個XMLReader。

用的最多的就是ContentHandler。ContentHandler是一個介面。建立出這個介面實現的執行個體後,可以將它設到parser中,parser在解析xml的過程中,會根據事件來回調ContentHandler中相應的方法。

xmlReader.setContentHandler(contentHandler);

除此之外還有setEntityResolver(EntityResolver), setDTDHandler(DTDHandler)和setErrorHandler(ErrorHandler)。這幾個從來沒有用過=_=。有用過的人沒?求usecase。。。

ContentHandler中相應的方法

ContentHandler是處理xml文檔最重要的類。其中的方法會在特定的事件發生時候被觸發。

startDocument(); // 此事件在開始解析文檔的時候觸發endDocument(); // 此事件在文檔解析結束後觸發startPrefixMapping(String prefix, String uri); // 此事件只有在setNamespaceAware為true的時候才會被觸發。每次遇到xmlns屬性後都會觸發一次。prefix 為去掉xmlns之後的內容,uri就是這個首碼對應的namespace。所以,如果想在setNamespaceAware為true的時候還得到這些attribute,除了setFeature之外,也可以處理這個事件,儲存相應的prefix-uri mappingendPrefixMapping(String prefix); //此事件在包含xmlns attribute的節點結束之後被觸發。對於wsdl來說,就是在觸發了wsdl:definitions的endElement之後觸發。startElement(String uri, String localName, String qName, Attributes atts); // 在一個node開始的時候觸發。如果setNamespaceAware為true,那麼uri的值就會被resolve,否則就會是空。localName則是節點的名字,比如對於wsdl:definitions來說,就是definitions。qName就是node的全名,比如wsdl:definitions。atts就是這個node的所有屬性。但是這時候會沒有xmlns的屬性。如果setNamespaceAware為false,那麼就不對uri解析。uri就是空,localName也是空,qName就是xs:sequence這種節點的名字。atts則會返回節點所有屬性的k-v mapping。endElement(String uri, String localName, String qName); //在節點處理完畢後觸發。參數值與startElement意義相同。characters(char ch[], int start, int length); // 在node的開始結束之前如果有字元,則會觸發此事件。比如 <nodeA>some character</nodeA>。在startElement nodeA之後,endElement nodeA之前,會調用characters方法,用new String(ch, start, length)建立出來的字串就是"some character"。這個方法需要注意的一點是,如果節點中的內容有多行,那麼這個方法有可能會被調用多次。也就是可能會(沒有驗證過)每一行都調用一次characters。還有需要注意的一點是,建立出來的字串已經包含了斷行符號換行ignorableWhitespace(char[], int, int); // 文檔說Receive notification of ignorable whitespace in element content. 具體啥意思沒試過。好像和validator有關。求解答。。。processingInstruction(String target, String data); // 當xml有PI的時候被觸發。但是xml最開始的PI不會觸發,就是那個<?xml version="1.0" encoding="UTF-8"?>,是不會觸發此事件的。除此之外,xml裡的PI都會被處理。比如<?testpi key1="value1" key2="value2"?>就會被觸發兩次,target都是testpi,data兩次分別是key1="value1"和key2="value2"。skippedEntity(String); // 文檔說Receive notification of a skipped entity. 不知道啥意思,求解答。。。setDocumentLocator (Locator locator); // 這個方法也很有用,parser會在處理文檔之前調用此方法。如果你需要知道當前處理到文檔的第幾行第幾列,就需要實現這個方法。實現不需要做什麼處理,只要在自己的ContentHandler裡建立一個Locator類型的成員變數,用這個成員變數儲存傳進來的參數,然後記得調用super.setDocumentLocator。parser會即時更新Locator中的變數值。通過Locator的getLineNumber和getColumnNumber可以得到當前處理的行和列。還有publicID,systemID,不知道是做啥用的。

基本上這些內容就夠解析xml用的了。

順道問問題

除了文章中說的幾個不清楚之外,還有個問題一直想知道答案。SAXP處理xml,一般處理一點就找到要找的東西了,下面一大半xml就不用處理了,那有沒有什麼辦法讓parser終止繼續處理?做個boolean標記,parser總歸還是要把xml走一遍的,如果xml很大,或者是遠端xml,那麼就會比較有用了。

在stackoverflow上找到瞭解答 http://stackoverflow.com/questions/2964315/java-sax-parser-how-to-manually-break-parsing

簡單來說就是在處理完畢,確定不需要繼續處理的時候,直接拋個異常。。。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.