3.使用sax解析xml文檔(我的JavaEE筆記)

注意:使用sax編程只能進(jìn)行查詢操作蹋嵌。

1暇屋、在使用DOM解析XML文檔時加匈,需要讀取整個XML文檔,在內(nèi)存中構(gòu)架代表整個DOM樹的Document對象淋叶,從而再對XML文檔進(jìn)行操作阎曹。此中情況下,如果XML文檔特別大,就會消耗計(jì)算機(jī)大量內(nèi)存芬膝,并且容易導(dǎo)致內(nèi)存溢出望门。

2、 SAX解析允許在讀取文檔的時候锰霜,立即對文檔進(jìn)行處理筹误,而不必等到整個文檔裝載完才會對文檔進(jìn)行操作。

3癣缅、SAX采用事件處理的方式解析XML文件厨剪,利用SAX解析XML文檔,涉及兩個部分:解析器和事件處理器友存。
3.1 解析器可以使用JAXP的API創(chuàng)建祷膳,創(chuàng)建出SAX解析器后,就可以指定解析器去解析某個XML文檔屡立。
3.2 解析器采用SAX方式在解析某個XML文檔時直晨,它只要解析到文檔的一個組成部分,都會去調(diào)用事件處理器的一個方法膨俐,解析器在調(diào)用事件處理器的方法時勇皇,會把當(dāng)前解析到的xml文件內(nèi)容作為方法的參數(shù)傳遞給事件處理器。
3.3 事件處理器由程序員編寫焚刺,程序員通過事件處理器中方法的參數(shù)敛摘,就可以很輕松地得到SAX解析器解析到的數(shù)據(jù),從而可以決定如何對數(shù)據(jù)進(jìn)行處理乳愉。

1.jpg

操作步驟:
(1)使用SAXParserFactory創(chuàng)建sax解析工廠:

SAXParserFactory spf = SAXParserFactory.newInstance();

(2)通過sax解析工廠得到解析器對象

    SAXParser sp = spf.newSAXParser();

(3)通過解析器對象得到一個xml的讀取器

    XMLReader xmlReader = sp.getXMLReader();

(4)設(shè)置讀取器的事件處理器兄淫,這個事件處理器需要程序員自己實(shí)現(xiàn)

    xmlReader.setContentHandler(new BookParserHandler());

(5)解析xml文件

xmlReader.parse("book.xml");

例子:這里我們還是解析之前的book.xml文檔

xml/book.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<書架>
    <書 name="yyy">
        <售價>109</售價>
        <售價>39元</售價>
        <書名>Java就業(yè)培訓(xùn)教程</書名>
        <作者>張孝祥</作者>
        <售價>120</售價></書>
</書架>

測試類:

src/sax.Demo1.java

package sax;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class Demo1 {

    public static void main(String[] args) throws Exception {
        //創(chuàng)建一個sax解析器工廠
        SAXParserFactory factory = SAXParserFactory.newInstance();
        //得到一個解析器對象
        SAXParser parser = factory.newSAXParser();
        //通過解析器得到一個xml的讀取器
        XMLReader reader = parser.getXMLReader();
        
        //在解析xml文檔之前,設(shè)置好事件處理器
        //我們一般不使用繼承ContentHandler接口的這種方式蔓姚,因?yàn)樾枰獙?shí)現(xiàn)的方法太多了
        //reader.setContentHandler(new MyContentHandler());
        reader.setContentHandler(new MyContentHandler2());
        
        //利用reader讀取xml文檔
        reader.parse("xml/book.xml");
    }
}
//繼承ContentHandler這個接口的方法只需要了解
class MyContentHandler implements ContentHandler{
    //這里我們先看繼承ContentHandler的情況捕虽,這個接口中需要實(shí)現(xiàn)的方法很多,但是
    //只用到下面前面三個方法赂乐。
    
    //此方法主要是進(jìn)行文本處理薯鳍,數(shù)組中得到文本,就是用來得到標(biāo)簽中的值
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        System.out.println("當(dāng)前解析到了:" + new String(ch, start, length));
        
    }
    
    //接收元素開始的通知挨措,主要處理開始標(biāo)簽
    //uri:名稱空間URI,如果元素沒有名稱空間URI崩溪,如果未執(zhí)行名稱空間處理浅役,則為空字符串
    //localName:本地名稱(不帶前綴),如果未執(zhí)行命名空間處理伶唯,則為空字符串
    //qName:元素名(帶有前綴)觉既,如果元素名不可用,則為空字符串
    //atts:該元素的屬性。如果沒有屬性瞪讼,則它將是空Attributes對象钧椰。在startElement返回后,
    //此對象的值是未定義的
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        System.out.println("當(dāng)前解析到了:" + qName + "符欠, 這個標(biāo)簽是開始標(biāo)簽");
        for(int i = 0; i < atts.getLength(); i++){
            //下面是得到標(biāo)簽中屬性和屬性的值
            String attname = atts.getQName(i);
            String attvalue = atts.getValue(i);
            System.out.println(attname + "=" + attvalue);
        }
        
    }
    //主要處理結(jié)束標(biāo)簽
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("當(dāng)前解析到了:" + qName + "嫡霞, 這個標(biāo)簽是結(jié)束標(biāo)簽");
        
    }
    
    
    @Override
    public void setDocumentLocator(Locator locator) {
        // TODO Auto-generated method stub
        
    }
    //接收文檔開始的通知,SAX解析器僅調(diào)用該方法一次
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        
    }
    //接收文檔結(jié)尾的通知希柿,SAX解析器僅調(diào)用該方法一次诊沪,并且它將是解析期間最后調(diào)用的方法。
    //直到解析器放棄解析(由于不可恢復(fù)的錯誤)或到達(dá)輸入的結(jié)尾時曾撤,該方法才會被調(diào)用
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    public void startPrefixMapping(String prefix, String uri) throws SAXException {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    public void endPrefixMapping(String prefix) throws SAXException {
        // TODO Auto-generated method stub
        
    }
    @Override
    public void ignorableWhitespace(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    public void processingInstruction(String target, String data)
            throws SAXException {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    public void skippedEntity(String name) throws SAXException {
        // TODO Auto-generated method stub
        
    }

}
//鑒于繼承ContentHandler接口需要實(shí)現(xiàn)的方法太多端姚,這里我們繼承DefaultHandler類
class MyContentHandler2 extends DefaultHandler{
    
    
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        System.out.println("當(dāng)前解析到了:" + qName + ", 這個標(biāo)簽是開始標(biāo)簽");
        for(int i = 0; i < atts.getLength(); i++){
            //下面是得到標(biāo)簽中屬性和屬性的值
            String attname = atts.getQName(i);
            String attvalue = atts.getValue(i);
            System.out.println(attname + "=" + attvalue);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("當(dāng)前解析到了:" + qName + "挤悉, 這個標(biāo)簽是結(jié)束標(biāo)簽");
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        System.out.println("當(dāng)前解析到了:" + new String(ch, start, length));
    }
    
}

這里我們可能已經(jīng)注意到了渐裸,繼承ContentHandler接口 和繼承DefaultHandler類所需要實(shí)現(xiàn)的方法都是一樣的,也完全可以寫成一樣的實(shí)現(xiàn)装悲,但是由于繼承ContentHandler所需要實(shí)現(xiàn)的類太多昏鹃,我們一般使用繼承DefaultHandler類完成對xml的解析。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末衅斩,一起剝皮案震驚了整個濱河市盆顾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌畏梆,老刑警劉巖您宪,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奠涌,居然都是意外死亡宪巨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門溜畅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來捏卓,“玉大人,你說我怎么就攤上這事慈格〉∏纾” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵浴捆,是天一觀的道長蒜田。 經(jīng)常有香客問我,道長选泻,這世上最難降的妖魔是什么冲粤? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任美莫,我火速辦了婚禮,結(jié)果婚禮上梯捕,老公的妹妹穿的比我還像新娘厢呵。我一直安慰自己,他們只是感情好傀顾,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布襟铭。 她就那樣靜靜地躺著,像睡著了一般锣笨。 火紅的嫁衣襯著肌膚如雪蝌矛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天错英,我揣著相機(jī)與錄音入撒,去河邊找鬼。 笑死椭岩,一個胖子當(dāng)著我的面吹牛茅逮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播判哥,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼献雅,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了塌计?” 一聲冷哼從身側(cè)響起挺身,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锌仅,沒想到半個月后章钾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡热芹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年贱傀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伊脓。...
    茶點(diǎn)故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡府寒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出报腔,到底是詐尸還是另有隱情株搔,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布纯蛾,位于F島的核電站邪狞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏茅撞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望米丘。 院中可真熱鬧剑令,春花似錦、人聲如沸拄查。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽堕扶。三九已至碍脏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稍算,已是汗流浹背典尾。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留糊探,地道東北人钾埂。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像科平,于是被迫代替她去往敵國和親褥紫。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 新增鏈接http://m.blog.csdn.net/article/details?id=7305068瞪慧,這一篇...
    來個芒果閱讀 1,366評論 0 1
  • 1. XML總結(jié) 1.1. XML簡介 XML : 可擴(kuò)展的標(biāo)記語言髓考。(和HTML非常類似的) 可擴(kuò)展的。 自定義...
    Ethan_Walker閱讀 3,045評論 0 12
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法弃酌,類相關(guān)的語法氨菇,內(nèi)部類的語法,繼承相關(guān)的語法矢腻,異常的語法门驾,線程的語...
    子非魚_t_閱讀 31,665評論 18 399
  • 一、緒論 上周工作需要了解項(xiàng)目的一些大體內(nèi)容多柑,結(jié)果在xml解析這一塊看的迷迷糊糊的奶是,所以在這里把學(xué)習(xí)到xm...
    cao健強(qiáng)閱讀 4,046評論 1 7
  • 接納自己與別人的相同點(diǎn),接納自己與別人的不同點(diǎn)竣灌,就像一年有四季 聂沙,各有各的不同。嘗試用文字去梳理自己的感受初嘹,去沉淀...
    b49f7e0ba112閱讀 181評論 0 0