日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

SAX解析XML 详解

發布時間:2025/4/5 asp.net 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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();??
  • ????}??
  • ????/*?
  • ?????*?接收字符數據的通知。?
  • ?????*?在DOM中?ch[begin:end]?相當于Text節點的節點值(nodeValue)?
  • ?????*/??
  • ????@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");??
  • ????}??
  • ??
  • ??????
  • ????/*?
  • ?????*?接收文檔的結尾的通知。?
  • ?????*?參數意義如下:?
  • ?????*????uri?:元素的命名空間?
  • ?????*????localName?:元素的本地名稱(不帶前綴)?
  • ?????*????qName?:元素的限定名(帶前綴)?
  • ?????*??
  • ?????*/??
  • ????@Override??
  • ????public?void?endElement(String?uri,String?localName,String?qName)??
  • ????????????throws?SAXException?{??
  • ????????System.out.println(this.toBlankString(--this.frontBlankCount)+??
  • ????????????????">>>?end?element?:?"+qName+"("+uri+")");??
  • ????}??
  • ??
  • ????/*?
  • ?????*?結束前綴?URI?范圍的映射。?
  • ?????*/??
  • ????@Override??
  • ????public?void?endPrefixMapping(String?prefix)?throws?SAXException?{??
  • ????????System.out.println(this.toBlankString(--this.frontBlankCount)+??
  • ????????????????">>>?end?prefix_mapping?:?"+prefix);??
  • ????}??
  • ??
  • ????/*?
  • ?????*?接收元素內容中可忽略的空白的通知。?
  • ?????*?參數意義如下:?
  • ?????*?????ch?:?來自?XML?文檔的字符?
  • ?????*?????start?:?數組中的開始位置?
  • ?????*?????length?:?從數組中讀取的字符的個數?
  • ?????*/??
  • ????@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());??
  • ????}??
  • ??????
  • ????/*?
  • ?????*?接收處理指令的通知。?
  • ?????*?參數意義如下:?
  • ?????*?????target?:?處理指令目標?
  • ?????*?????data?:?處理指令數據,如果未提供,則為?null。?
  • ?????*/??
  • ????@Override??
  • ????public?void?processingInstruction(String?target,String?data)??
  • ????????????throws?SAXException?{??
  • ????????System.out.println(this.toBlankString(this.frontBlankCount)+">>>?process?instruction?:?(target?=?\""??
  • ????????????????+target+"\",data?=?\""+data+"\")");??
  • ????}??
  • ??
  • ????/*?
  • ?????*?接收用來查找?SAX?文檔事件起源的對象。?
  • ?????*?參數意義如下:?
  • ?????*?????locator?:?可以返回任何?SAX?文檔事件位置的對象?
  • ?????*/??
  • ????@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()+")");??
  • ??????????
  • ????}??
  • ??
  • ????/*?
  • ?????*?接收跳過的實體的通知。?
  • ?????*?參數意義如下:??
  • ?????*?????name?:?所跳過的實體的名稱。如果它是參數實體,則名稱將以?'%'?開頭,?
  • ?????*????????????如果它是外部?DTD?子集,則將是字符串?"[dtd]"?
  • ?????*/??
  • ????@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?");??
  • ????}??
  • ??
  • ????/*?
  • ?????*?接收元素開始的通知。?
  • ?????*?參數意義如下:?
  • ?????*????uri?:元素的命名空間?
  • ?????*????localName?:元素的本地名稱(不帶前綴)?
  • ?????*????qName?:元素的限定名(帶前綴)?
  • ?????*????atts?:元素的屬性集合?
  • ?????*/??
  • ????@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+")");??
  • ????}??
  • ??????
  • ????/*?
  • ?????*?開始前綴?URI?名稱空間范圍映射。?
  • ?????*?此事件的信息對于常規的命名空間處理并非必需:?
  • ?????*?當?http://xml.org/sax/features/namespaces?功能為?true(默認)時,?
  • ?????*?SAX?XML?讀取器將自動替換元素和屬性名稱的前綴。?
  • ?????*?參數意義如下:?
  • ?????*????prefix?:前綴?
  • ?????*????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?{??
  • ??
  • ????/*?
  • ?????*?接收注釋聲明事件的通知。?
  • ?????*?參數意義如下:?
  • ?????*?????name?-?注釋名稱。?
  • ?????*?????publicId?-?注釋的公共標識符,如果未提供,則為?null。?
  • ?????*?????systemId?-?注釋的系統標識符,如果未提供,則為?null。?
  • ?????*/??
  • ????@Override??
  • ????public?void?notationDecl(String?name,?String?publicId,?String?systemId)??
  • ????????????throws?SAXException?{??
  • ????????System.out.println(">>>?notation?declare?:?(name?=?"+name??
  • ????????????????+",systemId?=?"+publicId??
  • ????????????????+",publicId?=?"+systemId+")");??
  • ????}??
  • ??
  • ????/*?
  • ?????*?接收未解析的實體聲明事件的通知。?
  • ?????*?參數意義如下:?
  • ?????*?????name?-?未解析的實體的名稱。?
  • ?????*?????publicId?-?實體的公共標識符,如果未提供,則為?null。?
  • ?????*?????systemId?-?實體的系統標識符。?
  • ?????*?????notationName?-?相關注釋的名稱。?
  • ?????*/??
  • ????@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?{??
  • ??
  • ????/*?
  • ?????*?允許應用程序解析外部實體。?
  • ?????*?解析器將在打開任何外部實體(頂級文檔實體除外)前調用此方法?
  • ?????*?參數意義如下:?
  • ?????*?????publicId?:?被引用的外部實體的公共標識符,如果未提供,則為?null。?
  • ?????*?????systemId?:?被引用的外部實體的系統標識符。?
  • ?????*?返回:?
  • ?????*?????一個描述新輸入源的?InputSource?對象,或者返回?null,?
  • ?????*?????以請求解析器打開到系統標識符的常規?URI?連接。?
  • ?????*/??
  • ????@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();??
  • ????????//創建處理DTD相關事件的處理器??
  • ????????DTDHandler?dtdHandler?=?new?MyDTDHandler();??
  • ????????//創建實體解析器??
  • ????????EntityResolver?entityResolver?=?new?MyEntityResolver();??
  • ??????????
  • ????????//創建一個XML解析器(通過SAX方式讀取解析XML)??
  • ????????XMLReader?reader?=?XMLReaderFactory.createXMLReader();???
  • ????????/*?
  • ?????????*?設置解析器的相關特性?
  • ?????????*?????http://xml.org/sax/features/validation?=?true?表示開啟驗證特性?
  • ?????????*?????http://xml.org/sax/features/namespaces?=?true?表示開啟命名空間特性?
  • ?????????*/??
  • ????????reader.setFeature("http://xml.org/sax/features/validation",true);??
  • ????????reader.setFeature("http://xml.org/sax/features/namespaces",true);??
  • ????????//設置XML解析器的處理文檔內容相關事件的處理器??
  • ????????reader.setContentHandler(contentHandler);??
  • ????????//設置XML解析器的處理錯誤事件處理器??
  • ????????reader.setErrorHandler(errorHandler);??
  • ????????//設置XML解析器的處理DTD相關事件的處理器??
  • ????????reader.setDTDHandler(dtdHandler);??
  • ????????//設置XML解析器的實體解析器??
  • ????????reader.setEntityResolver(entityResolver);??
  • ????????//解析books.xml文檔??
  • ????????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">??
  • ????<!--books's?comment-->??
  • ????<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 详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。