Android XML文件解析的方法介紹

目錄

SAX(Simple API XML)

DOM(Document Object Model)

Pull ------?谷歌官方推薦


DOM方式最直觀和容易理解催式,但是只適合XML文檔較小的時候使用昵慌,而SAX方式更適合在移動終端系統(tǒng)中使用,因為相比DOM占用內(nèi)存少,適合處理比較大的XML文檔鹉梨,最后的Pull方式使用場合和SAX類似,但是更適合需要提前結(jié)束XML文檔解析的場合。



SAX

SAX解析器是一種基于事件的解析器猜憎,事件驅(qū)動的流式解析方式是爬泥,從文件的開始順序解析到文檔的結(jié)束踩官,不可暫陀毕担或倒退。?

優(yōu)點:解析速度快,占用內(nèi)存少莲绰。非常適合在Android移動設(shè)備中使用栅哀。?

缺點:不會記錄標簽的關(guān)系,而要讓你的應用程序自己處理沦偎,這樣就增加了你程序的負擔谈火。?

工作原理:對文檔進行順序掃描,當掃描到文檔(document)開始與結(jié)束革为、元素(element)開始與結(jié)束系任、文檔 (document)結(jié)束等地方時通知事件處理函數(shù)霜旧,由事件處理函數(shù)做相應動作以清,然后繼續(xù)同樣的掃描,直至文檔結(jié)束崎逃。?



public class ContentHandler extends DefaultHandler{

? ? private String nodeName;

? ? private StringBuilder id;

? ? private StringBuilder name;

? ? private StringBuilder version;

? ? private String TAG = "SAX";

? ? //開始解析 XML 文檔? ?

? ? @Override? ?

? ? public void startDocument() throws SAXException {

? ? ? ? id = new StringBuilder();

? ? ? ? name = new StringBuilder();

? ? ? ? version = new StringBuilder();

? ? }

? ? //開始解析結(jié)點? ?

? ?@Override? ?

? ?public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

? ? //localName 記錄當前結(jié)點的名字? ? ? ? nodeName = localName;

? ? }

? ? //開始提取結(jié)點中內(nèi)容? ?

? ?@Override? ?

? ?public void characters(char[] ch, int start, int length) throws SAXException {

? ? ? ? if("id".equals(nodeName))

? ? ? ? ? ? id.append(ch,start,length);

? ? ? ? else if("name".equals(nodeName))

? ? ? ? ? ? name.append(ch,start,length);

? ? ? ? else if("version".equals(nodeName))

? ? ? ? ? ? version.append(ch,start, length);

? ? }

? ? //結(jié)束結(jié)點解析? ?

? ?@Override

? public void endElement(String uri, String localName, String qName) throws SAXException {

? ? ? ? if("app".equals(localName)){

? ? ? ? ? ? //可能包含回車或換行符? ? ? ? ? ? Log.d(TAG, "endElement: id = " + id.toString().trim());

? ? ? ? ? ? Log.d(TAG, "endElement: name = "+ name.toString().trim());

? ? ? ? ? ? Log.d(TAG, "endElement: version = "+ version.toString().trim());

? ? ? ? ? ? //打印結(jié)束后清空掷倔,否則會影響下一次內(nèi)容的讀取? ? ? ? ? ? id.setLength(0);

? ? ? ? ? ? name.setLength(0);

? ? ? ? ? ? version.setLength(0);

? ? ? ? }

? ? }

? ? //結(jié)束XML文檔解析? ?

? ?@Override? ?

? ?public void endDocument() throws SAXException {

? ? }

}

//用SAX方式解析XML

private void paraseXMLWithSAX(String xmlData){

? ? try {

? ? ? ? SAXParserFactory factory = SAXParserFactory.newInstance();

? ? ? ? XMLReader reader = factory.newSAXParser().getXMLReader();

? ? ? ? ContentHandler handler = new ContentHandler();

? ? ? //將contentHandler的實例設(shè)置到XMLReader中? ? ? reader.setContentHandler(handler);

? ? ? //開始解析? ? ? reader.parse(new InputSource(new StringReader(xmlData)));

? }catch(Exception e){

? ? ? ? e.printStackTrace();

? }

}

Pull 方式解析

PULL解析器的運行方式和SAX類似泽裳,都是基于事件的模式苹熏。不同的是,在PULL解析過程中返回的是數(shù)字惰拱,且我們需要自己獲取產(chǎn)生的事件然后做相應的操作巴柿,而不像SAX那樣由處理器觸發(fā)一種事件的方法凛虽,執(zhí)行我們的代碼。?

**解析過程:**XML pull提供了開始元素和結(jié)束元素广恢。當某個元素開始時凯旋,我們可以調(diào)用parser.nextText從XML文檔中提取所有字符數(shù)據(jù)。當解釋到一個文檔結(jié)束時钉迷,自動生成EndDocument事件至非。

讀取到xml的聲明返回 START_DOCUMENT;?

讀取到xml的開始標簽返回 START_TAG?

讀取到xml的文本返回 TEXT?

讀取到xml的結(jié)束標簽返回 END_TAG?

讀取到xml的結(jié)束返回 END_DOCUMENT

優(yōu)點:?PULL解析器小巧輕便,解析速度快糠聪,簡單易用睡蟋,非常適合在Android移動設(shè)備中使用,Android系統(tǒng)內(nèi)部在解析各種XML時也是用PULL解析器枷颊,Android官方推薦開發(fā)者們使用Pull解析技術(shù)戳杀。Pull解析技術(shù)是第三方開發(fā)的開源技術(shù),它同樣可以應用于JavaSE開發(fā)夭苗。

//用Pull方式解析XML

private void parseXMLWithPull(String xmlData){

? try {

? ? XmlPullParserFactory? factory = XmlPullParserFactory.newInstance();

? ? XmlPullParser xmlPullParser = factory.newPullParser();

? ? //設(shè)置輸入的內(nèi)容? ? xmlPullParser.setInput(new StringReader(xmlData));

? ? //獲取當前解析事件信卡,返回的是數(shù)字? ? int eventType = xmlPullParser.getEventType();

? ? //保存內(nèi)容? ? String id = "";

? ? String name = "";

? ? String version="";

? ? while (eventType != (XmlPullParser.END_DOCUMENT)){

? ? ? ? ? String nodeName = xmlPullParser.getName();

? ? ? ? ? switch (eventType){

? ? ? ? ? //開始解析XML? ? ? ? ? case XmlPullParser.START_TAG:{

? ? ? ? ? ? ? //nextText()用于獲取結(jié)點內(nèi)的具體內(nèi)容? ? ? ? ? ? ? if("id".equals(nodeName))

? ? ? ? ? ? ? ? ? id = xmlPullParser.nextText();

? ? ? ? ? ? ? else if("name".equals(nodeName))

? ? ? ? ? ? ? ? ? name = xmlPullParser.nextText();

? ? ? ? ? ? ? ? else if("version".equals(nodeName))

? ? ? ? ? ? ? ? ? version = xmlPullParser.nextText();

? ? ? ? ? ? } break;

? ? ? ? ? //結(jié)束解析? ? ? ? ? case XmlPullParser.END_TAG:{

? ? ? ? ? ? ? ? if("app".equals(nodeName)){

? ? ? ? ? ? ? ? ? Log.d(TAG, "parseXMLWithPull: id is "+ id);

? ? ? ? ? ? ? ? ? Log.d(TAG, "parseXMLWithPull: name is "+ name);

? ? ? ? ? ? ? ? ? Log.d(TAG, "parseXMLWithPull: version is "+ version);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? } break;

? ? ? ? ? default: break;

? ? ? ? ? }

? ? ? ? ? //下一個? ? ? ? ? eventType = xmlPullParser.next();

? ? }

? ? } catch (Exception e) {

? ? ? ? e.printStackTrace();

? ? }

}

DOM方式解析

DOM,即對象文檔模型题造,它是將整個XML文檔載入內(nèi)存(所以效率較低傍菇,不推薦使用),每一個節(jié)點當做一個對象界赔,結(jié)合代碼分析丢习。DOM實現(xiàn)時首先為XML文檔的解析定義一組接口牵触,解析器讀入整個文檔,然后構(gòu)造一個駐留內(nèi)存的樹結(jié)構(gòu)咐低,這樣代碼就可以使用DOM接口來操作整個樹結(jié)構(gòu)揽思。 由于DOM在內(nèi)存中以樹形結(jié)構(gòu)存放,因此檢索和更新效率會更高见擦。但是對于特別大的文檔钉汗,解析和加載整個文檔將會很耗資源。 當然鲤屡,如果XML文件的內(nèi)容比較小损痰,采用DOM是可行的。?

工作原理:使用DOM對XML文件進行操作時酒来,首先要解析文件卢未,將文件分為獨立的元素、屬性和注釋等堰汉,然后以節(jié)點樹的形式在內(nèi)存中對XML文件進行表示尝丐,就可以通過節(jié)點樹訪問文檔的內(nèi)容,并根據(jù)需要修改文檔衡奥。

使用步驟:

首先利用DocumentBuilderFactory創(chuàng)建一個DocumentBuilderFactory實例

然后利用DocumentBuilderFactory創(chuàng)建DocumentBuilder

然后加載XML文檔(Document)

然后獲取文檔的根結(jié)點(Element)爹袁,

然后獲取根結(jié)點中所有子節(jié)點的列表(NodeList),

然后使用再獲取子節(jié)點列表中的需要讀取的結(jié)點矮固。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末失息,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子档址,更是在濱河造成了極大的恐慌盹兢,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件守伸,死亡現(xiàn)場離奇詭異绎秒,居然都是意外死亡,警方通過查閱死者的電腦和手機尼摹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門见芹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蠢涝,你說我怎么就攤上這事玄呛。” “怎么了和二?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵徘铝,是天一觀的道長。 經(jīng)常有香客問我,道長惕它,這世上最難降的妖魔是什么怕午? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮淹魄,結(jié)果婚禮上郁惜,老公的妹妹穿的比我還像新娘。我一直安慰自己揭北,他們只是感情好,可當我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布吏颖。 她就那樣靜靜地躺著搔体,像睡著了一般。 火紅的嫁衣襯著肌膚如雪半醉。 梳的紋絲不亂的頭發(fā)上疚俱,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音缩多,去河邊找鬼呆奕。 笑死,一個胖子當著我的面吹牛衬吆,可吹牛的內(nèi)容都是我干的梁钾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼逊抡,長吁一口氣:“原來是場噩夢啊……” “哼姆泻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起冒嫡,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤拇勃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后孝凌,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體方咆,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年蟀架,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓣赂。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡片拍,死狀恐怖钩述,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情穆碎,我是刑警寧澤牙勘,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響方面,放射性物質(zhì)發(fā)生泄漏放钦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一恭金、第九天 我趴在偏房一處隱蔽的房頂上張望操禀。 院中可真熱鬧,春花似錦横腿、人聲如沸颓屑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽揪惦。三九已至,卻和暖如春罗侯,著一層夾襖步出監(jiān)牢的瞬間器腋,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工钩杰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留纫塌,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓讲弄,卻偏偏與公主長得像措左,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子避除,可洞房花燭夜當晚...
    茶點故事閱讀 44,619評論 2 354

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

  • 1 XML解析No29 【 XML:可拓展標記語言媳荒,語言和HTML類似,也是一種標記語言驹饺。 特點:標記是自定義...
    征程_Journey閱讀 1,648評論 0 9
  • 一钳枕、緒論 上周工作需要了解項目的一些大體內(nèi)容,結(jié)果在xml解析這一塊看的迷迷糊糊的赏壹,所以在這里把學習到xm...
    cao健強閱讀 4,035評論 1 7
  • 一鱼炒、DOM解析XML 我們首先來看看DOM(Document Object Model)這種方式解析xml,通過D...
    小董666閱讀 338評論 0 1
  • 1. XML總結(jié) 1.1. XML簡介 XML : 可擴展的標記語言蝌借。(和HTML非常類似的) 可擴展的昔瞧。 自定義...
    Ethan_Walker閱讀 3,021評論 0 12
  • 一篇文章由七個要素組成自晰,每個要素相輔相成。 標題稍坯,標題要能吸引人酬荞。 格式搓劫,即文章的排版,要看起來舒服混巧,代表顏值枪向。 ...
    德飛商學院閱讀 655評論 1 2