這篇文章給大家分享的是有關(guān)XML中SAX的示例分析的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
成都創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)澤庫,10余年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
在使用DOM解析XML文檔時(shí),需要讀取整個(gè)XML文檔,在內(nèi)存中構(gòu)建整個(gè)DOM樹的Document對象,從而再對XML文檔進(jìn)行操作。此種情況下,如果XML文檔特別大,就會消耗計(jì)算機(jī)的大量內(nèi)存,嚴(yán)重的情況下可能還會導(dǎo)致內(nèi)存溢出。
SAX解析允許在讀取文檔的時(shí)候,即對文檔進(jìn)行處理,而不必等到整個(gè)文檔裝載完才對文檔進(jìn)行操作。
通過繼承DefaultHandler
,來開發(fā)一個(gè)SAX解析器
【注意】SAX主要用于對XML文檔的解析,不能去修改、刪除和添加元素。
sax是一種推式的機(jī)制,你創(chuàng)建一個(gè)sax解析器,解析器在發(fā)現(xiàn)xml文檔中的內(nèi)容時(shí)就告訴你(把事件推給你,有點(diǎn)類似于java swing中的事件監(jiān)聽)。如何處理這些發(fā)現(xiàn)的內(nèi)容,由程序員自己決定。
在基于sax的程序中,有五個(gè)最常用的sax事件:
1.startDocument()–>告訴你解析器發(fā)現(xiàn)了文檔的開始,告訴你解析器開始掃描文檔
2.endDocument()–>告訴你解析器發(fā)現(xiàn)了文檔結(jié)尾
3.startElement()–>告訴你解析器發(fā)現(xiàn)了一個(gè)起始標(biāo)簽,該事件告訴你標(biāo)簽的名稱、該元素所有的屬性名和值
4.characters()–>告訴你解析器發(fā)現(xiàn)了一些文本,將得到一個(gè)字符數(shù)組,該數(shù)組的偏移量和一個(gè)長度偏移量,有這三個(gè)變量你可以得到解析器發(fā)現(xiàn)的文本
5.endElement()–>告訴你解析器發(fā)現(xiàn)了一個(gè)結(jié)束標(biāo)簽,該事件告訴你元素的名稱
依然使用DOM解析中用到的XML例子,如下:
<班級> <學(xué)生 地址="香港"> <名字>周小星名字> <年齡>23年齡> <介紹>學(xué)習(xí)刻苦介紹> 學(xué)生> <學(xué)生 地址="澳門"> <名字>林曉名字> <年齡>25年齡> <介紹>是一個(gè)好學(xué)生介紹> 學(xué)生>班級>
【步驟】:
1.使用SAXParserFactory創(chuàng)建SAX解析工廠
SAXParserFactory spf = SAXParserFactory.newInstance();
2.通過SAX解析工廠得到解析器對象
SAXParser sp = spf.newSAXParser();
3.將解析對象和事件處理器對象關(guān)聯(lián)
sp.parse("src/myClass.xml",new MyHandler());
這里的MyHandler
需要自己定義,并且它要繼承DefaultHandler
,然后在MyHandler
類中重寫上文提到的5個(gè)sax事件方法,當(dāng)然也可以只重寫自己需要的。
比如現(xiàn)在我寫的MyHandler
如下:
class MyHandler extends DefaultHandler{ /** * 發(fā)現(xiàn)文檔開始,該函數(shù)只會被調(diào)用一次 */ @Override public void startDocument() throws SAXException { System.out.println("startDocument"); } /** * 發(fā)現(xiàn)文檔結(jié)束,該函數(shù)只會被調(diào)用一次 */ @Override public void endDocument() throws SAXException { System.out.println("endDocument"); } /** * 發(fā)現(xiàn)XML中的一個(gè)元素開始,會被反復(fù)調(diào)用 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("元素名稱:"+qName); } /** * 發(fā)現(xiàn)XML中的一個(gè)元素結(jié)束,會被反復(fù)調(diào)用 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { } /** * 發(fā)現(xiàn)XML文件中的文本,會被反復(fù)調(diào)用 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { // 顯示文本內(nèi)容 String text = new String(ch,start,length); if(!text.trim().equals("")){ System.out.println(text); } } }
運(yùn)行結(jié)果如下:
可以看到,這是對XML文檔的一種遍歷,而sax能夠做的也只是遍歷了。
那么,如果現(xiàn)在我們有這樣一個(gè)需求:只顯示所有學(xué)生的姓名和年齡,不顯示學(xué)生的介紹,怎么實(shí)現(xiàn)呢?
我們可以在MyHandler
類中定義兩個(gè)布爾變量isName和isAge,在startElement
方法中標(biāo)識是否是姓名元素或者年齡元素,如果是的話才在characters
方法中獲取對應(yīng)的文本,如下:
1.定義兩個(gè)布爾變量
private boolean isName = false;private boolean isAge = false;
2.在startElement
方法中添加判斷
@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equals("名字")){ this.isName = true; }else if(qName.equals("年齡")){ this.isAge = true; } }
3.在characters
方法中根據(jù)標(biāo)識符進(jìn)行判斷是否獲取文本
@Overridepublic void characters(char[] ch, int start, int length) throws SAXException { // 顯示文本內(nèi)容 String text = new String(ch,start,length); if(!text.trim().equals("")&&(isName||isAge)){ System.out.println(text); } isName = false; isAge = false; }
最后要記得將兩個(gè)布爾變量復(fù)位成false。
運(yùn)行結(jié)果如下:
在使用DOM解析XML文檔時(shí),需要讀取整個(gè)XML文檔,在內(nèi)存中構(gòu)建整個(gè)DOM樹的Document對象,從而再對XML文檔進(jìn)行操作。此種情況下,如果XML文檔特別大,就會消耗計(jì)算機(jī)的大量內(nèi)存,嚴(yán)重的情況下可能還會導(dǎo)致內(nèi)存溢出。
SAX解析允許在讀取文檔的時(shí)候,即對文檔進(jìn)行處理,而不必等到整個(gè)文檔裝載完才對文檔進(jìn)行操作。
通過繼承DefaultHandler
,來開發(fā)一個(gè)SAX解析器
【注意】SAX主要用于對XML文檔的解析,不能去修改、刪除和添加元素。
sax是一種推式的機(jī)制,你創(chuàng)建一個(gè)sax解析器,解析器在發(fā)現(xiàn)xml文檔中的內(nèi)容時(shí)就告訴你(把事件推給你,有點(diǎn)類似于java swing中的事件監(jiān)聽)。如何處理這些發(fā)現(xiàn)的內(nèi)容,由程序員自己決定。
在基于sax的程序中,有五個(gè)最常用的sax事件:
1.startDocument()–>告訴你解析器發(fā)現(xiàn)了文檔的開始,告訴你解析器開始掃描文檔
2.endDocument()–>告訴你解析器發(fā)現(xiàn)了文檔結(jié)尾
3.startElement()–>告訴你解析器發(fā)現(xiàn)了一個(gè)起始標(biāo)簽,該事件告訴你標(biāo)簽的名稱、該元素所有的屬性名和值
4.characters()–>告訴你解析器發(fā)現(xiàn)了一些文本,將得到一個(gè)字符數(shù)組,該數(shù)組的偏移量和一個(gè)長度偏移量,有這三個(gè)變量你可以得到解析器發(fā)現(xiàn)的文本
5.endElement()–>告訴你解析器發(fā)現(xiàn)了一個(gè)結(jié)束標(biāo)簽,該事件告訴你元素的名稱
依然使用DOM解析中用到的XML例子,如下:
<班級> <學(xué)生 地址="香港"> <名字>周小星名字> <年齡>23年齡> <介紹>學(xué)習(xí)刻苦介紹> 學(xué)生> <學(xué)生 地址="澳門"> <名字>林曉名字> <年齡>25年齡> <介紹>是一個(gè)好學(xué)生介紹> 學(xué)生>班級>
【步驟】:
1.使用SAXParserFactory創(chuàng)建SAX解析工廠
SAXParserFactory spf = SAXParserFactory.newInstance();
2.通過SAX解析工廠得到解析器對象
SAXParser sp = spf.newSAXParser();
3.將解析對象和事件處理器對象關(guān)聯(lián)
sp.parse("src/myClass.xml",new MyHandler());
這里的MyHandler
需要自己定義,并且它要繼承DefaultHandler
,然后在MyHandler
類中重寫上文提到的5個(gè)sax事件方法,當(dāng)然也可以只重寫自己需要的。
比如現(xiàn)在我寫的MyHandler
如下:
class MyHandler extends DefaultHandler{ /** * 發(fā)現(xiàn)文檔開始,該函數(shù)只會被調(diào)用一次 */ @Override public void startDocument() throws SAXException { System.out.println("startDocument"); } /** * 發(fā)現(xiàn)文檔結(jié)束,該函數(shù)只會被調(diào)用一次 */ @Override public void endDocument() throws SAXException { System.out.println("endDocument"); } /** * 發(fā)現(xiàn)XML中的一個(gè)元素開始,會被反復(fù)調(diào)用 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("元素名稱:"+qName); } /** * 發(fā)現(xiàn)XML中的一個(gè)元素結(jié)束,會被反復(fù)調(diào)用 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { } /** * 發(fā)現(xiàn)XML文件中的文本,會被反復(fù)調(diào)用 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { // 顯示文本內(nèi)容 String text = new String(ch,start,length); if(!text.trim().equals("")){ System.out.println(text); } } }
運(yùn)行結(jié)果如下:
可以看到,這是對XML文檔的一種遍歷,而sax能夠做的也只是遍歷了。
那么,如果現(xiàn)在我們有這樣一個(gè)需求:只顯示所有學(xué)生的姓名和年齡,不顯示學(xué)生的介紹,怎么實(shí)現(xiàn)呢?
我們可以在MyHandler
類中定義兩個(gè)布爾變量isName和isAge,在startElement
方法中標(biāo)識是否是姓名元素或者年齡元素,如果是的話才在characters
方法中獲取對應(yīng)的文本,如下:
1.定義兩個(gè)布爾變量
private boolean isName = false;private boolean isAge = false;
2.在startElement
方法中添加判斷
@Overridepublic void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equals("名字")){ this.isName = true; }else if(qName.equals("年齡")){ this.isAge = true; } }
3.在characters
方法中根據(jù)標(biāo)識符進(jìn)行判斷是否獲取文本
@Overridepublic void characters(char[] ch, int start, int length) throws SAXException { // 顯示文本內(nèi)容 String text = new String(ch,start,length); if(!text.trim().equals("")&&(isName||isAge)){ System.out.println(text); } isName = false; isAge = false; }
最后要記得將兩個(gè)布爾變量復(fù)位成false。
運(yùn)行結(jié)果如下:
感謝各位的閱讀!關(guān)于“XML中SAX的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!