首先我們來瞭解一下SAX解析器的基本知識:
SAX(Simple API for XML)解析器是一種基於事件的解析器,事件驅動的流式解析方式是,從檔案的開始順序解析到文檔的結束,不可暫停或倒退。它的核心是事件處理模式,主要是圍繞著事件來源以及事件處理器來工作的。當事件來源產生事件後,呼叫事件處理器相應的處理方法,一個事件就可以得到處理。在事件來源呼叫事件處理器中特定方法的時候,還要傳遞給事件處理器相應事件的狀態資訊,這樣事件處理器才能夠根據提供的事件資訊來決定自己的行為。
SAX的工作原理:簡單地說就是對文檔進行順序掃描,當掃描到文檔(document)開始與結束、元素(element)開始與結束、文檔(document)結束等地方時通知事件處理函數,由事件處理函數做相應動作,然後繼續同樣的掃描,直至文檔結束。
然後我們通過一個小例子來看一下android中我們如何運用SAX去解析XML檔案:
(1)首先我們拷貝一個beauties.xml檔案到assets目錄下,其內容如下:
範冰冰 28 楊冪 23
(2) 然後在layout下面建立一個布局檔案saxtest.xml,其內容如下:
(3)在src目錄下建立一個與xml裡面的節點對應的一個類Beauty,內容如下:
package com.saxtest;public class Beauty {private String name;private String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "美女資料 [年齡=" + age + ", 姓名=" + name + "]";}}
再寫一個關鍵的類MySaxHandler,在這個類中我們將解析出來的字串產生了Beauty對象,並加入到List中,代碼已經詳細注釋,內容如下:
package com.saxtest;import java.util.ArrayList;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;public class MySaxHandler extends DefaultHandler{//聲明一個裝載Beauty類型的Listprivate ArrayList mList;//聲明一個Beauty類型的變數private Beauty beauty;//聲明一個字串變數private String content;/** * MySaxHandler的構造方法 * * @param list 裝載返回結果的List對象 */public MySaxHandler(ArrayList list){this.mList = list;}/** * 當SAX解析器解析到XML文檔開始時,會調用的方法 */@Overridepublic void startDocument() throws SAXException {super.startDocument();}/** * 當SAX解析器解析到XML文檔結束時,會調用的方法 */@Overridepublic void endDocument() throws SAXException {super.endDocument();}/** * 當SAX解析器解析到某個屬性值時,會調用的方法 * 其中參數ch記錄了這個屬性值的內容 */@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {super.characters(ch, start, length);content = new String(ch, start, length);}/** * 當SAX解析器解析到某個元素開始時,會調用的方法 * 其中localName記錄的是元素屬性名稱 */@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {super.startElement(uri, localName, qName, attributes);if("beauty".equals(localName)){beauty = new Beauty(); //建立Beauty對象}}/** * 當SAX解析器解析到某個元素結束時,會調用的方法 * 其中localName記錄的是元素屬性名稱 */@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {super.endElement(uri, localName, qName);if("name".equals(localName)){beauty.setName(content);}else if("age".equals(localName)){beauty.setAge(content);}else if("beauty".equals(localName)){mList.add(beauty); //將Beauty對象加入到List中}}}
第三個源檔案就是SaxTestActivity,這個Activity的布局檔案saxtest.xml,之前已經給出過它的內容,現在我們貼出Activity源碼的內容,代碼都已經詳細注釋了:
package com.saxtest;import java.io.InputStream;import java.util.ArrayList;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.InputSource;import org.xml.sax.XMLReader;import android.app.Activity;import android.content.res.AssetManager;import android.os.Bundle;import android.widget.TextView;import com.example.saxtest.R;public class SaxTestActivity extends Activity{//聲明裝載Beauty對象的Listprivate ArrayList beautyList;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.saxtest);//初始化beautyList鏈表if(beautyList == null){beautyList = new ArrayList();}doMyMission();setupViews();}/** * 使用SAX解析器解析XML檔案的方法 */private void doMyMission(){try {//擷取AssetManager管理器對象AssetManager as = this.getAssets();//通過AssetManager的open方法擷取到beauties.xml檔案的輸入資料流InputStream is = as.open("beauties.xml");//通過擷取到的InputStream來得到InputSource執行個體InputSource is2 = new InputSource(is);//使用Factory 方法初始化SAXParserFactory變數spfSAXParserFactory spf = SAXParserFactory.newInstance();//通過SAXParserFactory得到SAXParser的執行個體SAXParser sp = spf.newSAXParser();//通過SAXParser得到XMLReader的執行個體XMLReader xr = sp.getXMLReader();//初始化自訂的類MySaxHandler的變數msh,將beautyList傳遞給它,以便裝載資料MySaxHandler msh = new MySaxHandler(beautyList);//將對象msh傳遞給xrxr.setContentHandler(msh);//調用xr的parse方法解析輸入資料流xr.parse(is2);} catch (Exception e) {e.printStackTrace();}}/** * 將解析結果輸出到介面的方法 */private void setupViews(){String result = "";for (Beauty b : beautyList) { result += b.toString(); } TextView textView = (TextView) findViewById(R.id.textView); textView.setText(result); }}
右鍵運行工程代碼,結果如下:
Android之SAX解析XML