生活随笔
收集整理的這篇文章主要介紹了
SAX解析XML 详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
JAVA 解析 XML 通常有兩種方式,DOM?和?SAX。DOM 雖然是 W3C 的標準,提供了標準的解析方式,但它的解析效率一直不盡如人意,因為使用DOM解析XML時,解析器讀入整個文檔并構建一個駐留內存的樹結構(節點樹),然后您的代碼才可以使用 DOM 的標準接口來操作這個樹結構。但大部分情況下我們只對文檔的部分內容感興趣,根本就不用先解析整個文檔,并且從節點樹的根節點來索引一些我們需要的數據也是非常耗時的。?
??? SAX是一種XML解析的替代方法。相比于文檔對象模型DOM,SAX 是讀取和操作 XML 數據的更快速、更輕量的方
法。SAX 允許您在讀取文檔時處理它,從而不必等待整個文檔被存儲之后才采取操作。它不涉及 DOM 所必需的開銷和概念跳躍。?SAX API是一個基于事件的API?,適用于處理數據流,即隨著數據的流動而依次處理數據。SAX API?
在其解析您的文檔時發生一定事件的時候會通知您。在您對其響應時,您不作保存的數據將會 被拋棄。
??? 下面是一個SAX解析XML的示例(有點長,因為詳細注解了SAX事件處理的所有方法),SAX API中主要有四種處理事件的接口,它們分別是ContentHandler,DTDHandler,?EntityResolver?和?ErrorHandler?。下面的例子可能有點冗長,實際上只要繼承DefaultHandler?類 ,再覆蓋一部分 處理事件的方法 同樣可以達到這個示例的效果,但為了縱觀全局,還是看看SAX API里面所有主要的事件解析方法吧。( 實際上DefaultHandler就是實現了上面的四個事件處理器接口,然后提供了每個抽象方法的默認實現。)?
1,ContentHandler?接口 :接收文檔邏輯內容的通知 的處理器接口。
Java代碼??
import?org.xml.sax.Attributes;??import?org.xml.sax.ContentHandler;??import?org.xml.sax.Locator;??import?org.xml.sax.SAXException;????class?MyContentHandler?implements?ContentHandler{??????StringBuffer?jsonStringBuffer?;??????int?frontBlankCount?=?0;??????public?MyContentHandler(){??????????jsonStringBuffer?=?new?StringBuffer();??????}???????????????@Override??????public?void?characters(char[]?ch,?int?begin,?int?length)?throws?SAXException?{??????????StringBuffer?buffer?=?new?StringBuffer();??????????for(int?i?=?begin?;?i?<?begin+length?;?i++){??????????????switch(ch[i]){??????????????????case?'\\':buffer.append("\\\\");break;??????????????????case?'\r':buffer.append("\\r");break;??????????????????case?'\n':buffer.append("\\n");break;??????????????????case?'\t':buffer.append("\\t");break;??????????????????case?'\"':buffer.append("\\\"");break;??????????????????default?:?buffer.append(ch[i]);???????????????}??????????}??????????System.out.println(this.toBlankString(this.frontBlankCount)+??????????????????">>>?characters("+length+"):?"+buffer.toString());??????}??????????????????????@Override??????public?void?endDocument()?throws?SAXException?{??????????System.out.println(this.toBlankString(--this.frontBlankCount)+??????????????????">>>?end?document");??????}???????????????????????????@Override??????public?void?endElement(String?uri,String?localName,String?qName)??????????????throws?SAXException?{??????????System.out.println(this.toBlankString(--this.frontBlankCount)+??????????????????">>>?end?element?:?"+qName+"("+uri+")");??????}????????????????@Override??????public?void?endPrefixMapping(String?prefix)?throws?SAXException?{??????????System.out.println(this.toBlankString(--this.frontBlankCount)+??????????????????">>>?end?prefix_mapping?:?"+prefix);??????}????????????????????@Override??????public?void?ignorableWhitespace(char[]?ch,?int?begin,?int?length)??????????????throws?SAXException?{??????????StringBuffer?buffer?=?new?StringBuffer();??????????for(int?i?=?begin?;?i?<?begin+length?;?i++){??????????????switch(ch[i]){??????????????????case?'\\':buffer.append("\\\\");break;??????????????????case?'\r':buffer.append("\\r");break;??????????????????case?'\n':buffer.append("\\n");break;??????????????????case?'\t':buffer.append("\\t");break;??????????????????case?'\"':buffer.append("\\\"");break;??????????????????default?:?buffer.append(ch[i]);???????????????}??????????}??????????System.out.println(this.toBlankString(this.frontBlankCount)+">>>?ignorable?whitespace("+length+"):?"+buffer.toString());??????}???????????????????????@Override??????public?void?processingInstruction(String?target,String?data)??????????????throws?SAXException?{??????????System.out.println(this.toBlankString(this.frontBlankCount)+">>>?process?instruction?:?(target?=?\""??????????????????+target+"\",data?=?\""+data+"\")");??????}??????????????????@Override??????public?void?setDocumentLocator(Locator?locator)?{??????????System.out.println(this.toBlankString(this.frontBlankCount)+??????????????????">>>?set?document_locator?:?(lineNumber?=?"+locator.getLineNumber()??????????????????+",columnNumber?=?"+locator.getColumnNumber()??????????????????+",systemId?=?"+locator.getSystemId()??????????????????+",publicId?=?"+locator.getPublicId()+")");????????????????}???????????????????@Override??????public?void?skippedEntity(String?name)?throws?SAXException?{??????????System.out.println(this.toBlankString(this.frontBlankCount)+??????????????????">>>?skipped_entity?:?"+name);??????}????????????????@Override??????public?void?startDocument()?throws?SAXException?{??????????System.out.println(this.toBlankString(this.frontBlankCount++)+??????????????????">>>?start?document?");??????}?????????????????????@Override??????public?void?startElement(String?uri,?String?localName,?String?qName,???????????????Attributes?atts)?throws?SAXException?{??????????System.out.println(this.toBlankString(this.frontBlankCount++)+??????????????????">>>?start?element?:?"+qName+"("+uri+")");??????}??????????????????????????@Override??????public?void?startPrefixMapping(String?prefix,String?uri)??????????????throws?SAXException?{??????????System.out.println(this.toBlankString(this.frontBlankCount++)+??????????????????">>>?start?prefix_mapping?:?xmlns:"+prefix+"?=?"??????????????????+"\""+uri+"\"");????????????????}????????????private?String?toBlankString(int?count){??????????StringBuffer?buffer?=?new?StringBuffer();??????????for(int?i?=?0;i<count;i++)??????????????buffer.append("????");??????????return?buffer.toString();??????}????????}?? ?
2,DTDHandler?接口 :接收與 DTD 相關的事件的通知的處理器接口。
Java代碼??
import?org.xml.sax.DTDHandler;??import?org.xml.sax.SAXException;????public?class?MyDTDHandler?implements?DTDHandler?{????????????????????@Override??????public?void?notationDecl(String?name,?String?publicId,?String?systemId)??????????????throws?SAXException?{??????????System.out.println(">>>?notation?declare?:?(name?=?"+name??????????????????+",systemId?=?"+publicId??????????????????+",publicId?=?"+systemId+")");??????}?????????????????????@Override??????public?void?unparsedEntityDecl(String?name,??????????????String?publicId,??????????????String?systemId,??????????????String?notationName)?throws?SAXException?{??????????System.out.println(">>>?unparsed?entity?declare?:?(name?=?"+name??????????????????+",systemId?=?"+publicId??????????????????+",publicId?=?"+systemId??????????????????+",notationName?=?"+notationName+")");??????}????}?? ?
3,EntityResolver?接口 :是用于解析實體的基本接口。
Java代碼??
import?java.io.IOException;????import?org.xml.sax.EntityResolver;??import?org.xml.sax.InputSource;??import?org.xml.sax.SAXException;????public?class?MyEntityResolver?implements?EntityResolver?{???????????????????????@Override??????public?InputSource?resolveEntity(String?publicId,?String?systemId)??????????????throws?SAXException,?IOException?{??????????return?null;??????}????}?? ?
4,ErrorHandler接口 :是錯誤處理程序的基本接口。
Java代碼??
import?org.xml.sax.ErrorHandler;??import?org.xml.sax.SAXException;??import?org.xml.sax.SAXParseException;????public?class?MyErrorHandler?implements?ErrorHandler?{????????????????@Override??????public?void?error(SAXParseException?e)?throws?SAXException?{??????????System.err.println("Error?("+e.getLineNumber()+","??????????????????+e.getColumnNumber()+")?:?"+e.getMessage());??????}????????????????????@Override??????public?void?fatalError(SAXParseException?e)?throws?SAXException?{??????????System.err.println("FatalError?("+e.getLineNumber()+","??????????????????+e.getColumnNumber()+")?:?"+e.getMessage());??????}????????????????@Override??????public?void?warning(SAXParseException?e)?throws?SAXException?{??????????System.err.println("Warning?("+e.getLineNumber()+","??????????????????+e.getColumnNumber()+")?:?"+e.getMessage());??????}????}?? ?
Test?類的主方法打印解析books.xml時的事件信息。
Java代碼??
import?java.io.FileNotFoundException;??import?java.io.FileReader;??import?java.io.IOException;????import?org.xml.sax.ContentHandler;??import?org.xml.sax.DTDHandler;??import?org.xml.sax.EntityResolver;??import?org.xml.sax.ErrorHandler;??import?org.xml.sax.InputSource;??import?org.xml.sax.SAXException;??import?org.xml.sax.XMLReader;??import?org.xml.sax.helpers.XMLReaderFactory;??????public?class?Test?{????????public?static?void?main(String[]?args)?throws?SAXException,???????????????FileNotFoundException,?IOException?{????????????????????ContentHandler?contentHandler?=?new?MyContentHandler();????????????????????ErrorHandler?errorHandler?=?new?MyErrorHandler();????????????????????DTDHandler?dtdHandler?=?new?MyDTDHandler();????????????????????EntityResolver?entityResolver?=?new?MyEntityResolver();??????????????????????????????XMLReader?reader?=?XMLReaderFactory.createXMLReader();?????????????????????????reader.setFeature("http://xml.org/sax/features/validation",true);??????????reader.setFeature("http://xml.org/sax/features/namespaces",true);????????????????????reader.setContentHandler(contentHandler);????????????????????reader.setErrorHandler(errorHandler);????????????????????reader.setDTDHandler(dtdHandler);????????????????????reader.setEntityResolver(entityResolver);????????????????????reader.parse(new?InputSource(new?FileReader("books.xml")));??????}????}?? ?
books.xml?文件的內容如下:
?
Xml代碼??
<?xml?version="1.0"?encoding="GB2312"?>??<books??count="3"?xmlns="http://test.org/books">????????????<book?id="1">??????????<name>Thinking?in?JAVA</name>??????</book>??????<book?id="2">??????????<name>Core?JAVA2</name>??????</book>??????<book?id="3">??????????<name>C++?primer</name>??????</book>??</books>?? ?
控制臺輸出如下:
?
>>> set document_locator : (lineNumber = 1,columnNumber = 1,systemId = null,publicId = null)
>>> start document?
Error (2,7) : Document is invalid: no grammar found.
Error (2,7) : Document root element "books", must match DOCTYPE root "null".
??? >>> start prefix_mapping : xmlns: = "http://test.org/books"
??????? >>> start element : books(http://test.org/books)
??????????? >>> characters(2): \n\t
??????????? >>> characters(2): \n\t
??????????? >>> start element : book(http://test.org/books)
??????????????? >>> characters(3): \n\t\t
??????????????? >>> start element : name(http://test.org/books)
??????????????????? >>> characters(16): Thinking in JAVA
??????????????? >>> end element : name(http://test.org/books)
??????????????? >>> characters(2): \n\t
??????????? >>> end element : book(http://test.org/books)
??????????? >>> characters(2): \n\t
??????????? >>> start element : book(http://test.org/books)
??????????????? >>> characters(3): \n\t\t
??????????????? >>> start element : name(http://test.org/books)
??????????????????? >>> characters(10): Core JAVA2
??????????????? >>> end element : name(http://test.org/books)
??????????????? >>> characters(2): \n\t
??????????? >>> end element : book(http://test.org/books)
??????????? >>> characters(2): \n\t
??????????? >>> start element : book(http://test.org/books)
??????????????? >>> characters(3): \n\t\t
??????????????? >>> start element : name(http://test.org/books)
??????????????????? >>> characters(10): C++ primer
??????????????? >>> end element : name(http://test.org/books)
??????????????? >>> characters(2): \n\t
??????????? >>> end element : book(http://test.org/books)
??????????? >>> characters(1): \n
??????? >>> end element : books(http://test.org/books)
??? >>> end prefix_mapping :?
>>> end document
轉載于:https://www.cnblogs.com/duanxz/archive/2012/08/08/2628416.html
總結
以上是生活随笔為你收集整理的SAX解析XML 详解的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。