上一節中,我們使用SAX方式解析xml文檔, SAX方式是基於事件驅動的。當然android的事件機制是基於回呼函數的。在這一節中,我們用另外一種方式解析xml文檔,這種方式也是基於事件驅動的,與SAX方式一樣,它就是PULL方式。只不過PULL方式讀xml回調方法返回的是數字。
讀取到xml的聲明返回 START_DOCUMENT;
讀取到xml的結束返回 END_DOCUMENT ;
讀取到xml的開始標籤返回 START_TAG
讀取到xml的結束標籤返回 END_TAG
讀取到xml的文本返回 TEXT
xml資料結果還是採用我們先前使用的river.xml檔案。
採用PULL方式與SAX大同小異,重點在於我們需要知道導航到什麼標籤時候做什麼就行了,依據上一節SAX處理方式的思路,我們也可以在這一節中一樣處理,基本方法是:
基本處理方式是:當PULL解析器導航到文檔開始標籤時就開始執行個體化list集合用來存貯資料對象。導航到元素開始標籤時回判斷元素標籤類型,如果是river標籤,則需要執行個體化River對象了,如果是其他類型,則取得該標籤內容並賦予River對象。當然它也會導航到文字標籤,不過在這裡,我們可以不用。
根據以上的解釋,我們可以得出以下處理xml文檔邏輯:
1:當導航到XmlPullParser.START_DOCUMENT,可以不做處理,當然你可以執行個體化集合對象等等。
2:當導航到XmlPullParser.START_TAG,則判斷是否是river標籤,如果是,則執行個體化river對象,並調用getAttributeValue方法擷取標籤中屬性值。
3:當導航到其他標籤,比如Introduction時候,則判斷river對象是否為空白,如不為空白,則取出Introduction中的內容,nextText方法來擷取文本節點內容
4:當然啦,它一定會導航到XmlPullParser.END_TAG的,有開始就要有結束嘛。在這裡我們就需要判讀是否是river結束標籤,如果是,則把river對象存進list集合中了,並設定river對象為null.
由以上的處理邏輯,我們可以得出以下代碼:
View Code
public List<River> parse(String xmlPath){
List<River> rivers=new ArrayList<River>();
River river=null;
InputStream inputStream=null;
//獲得XmlPullParser解析器
XmlPullParser xmlParser = Xml.newPullParser();
try {
//得到檔案流,並設定編碼方式
inputStream=this.context.getResources().getAssets().open(xmlPath);
xmlParser.setInput(inputStream, "utf-8");
//獲得解析到的事件類別目錄,這裡有開始文檔,結束文檔,開始標籤,結束標籤,文本等等事件。
int evtType=xmlParser.getEventType();
//一直迴圈,直到文檔結束
while(evtType!=XmlPullParser.END_DOCUMENT){
switch(evtType){
case XmlPullParser.START_TAG:
String tag = xmlParser.getName();
//如果是river標籤開始,則說明需要執行個體化對象了
if (tag.equalsIgnoreCase(RIVER)) {
river = new River();
//取出river標籤中的一些屬性值
river.setName(xmlParser.getAttributeValue(null, NAME));
river.setLength(Integer.parseInt(xmlParser.getAttributeValue(null, LENGTH)));
}else if(river!=null){
//如果遇到introduction標籤,則讀取它內容
if(tag.equalsIgnoreCase(INTRODUCTION)){
river.setIntroduction(xmlParser.nextText());
}else if(tag.equalsIgnoreCase(IMAGEURL)){
river.setImageurl(xmlParser.nextText());
}
}
break;
case XmlPullParser.END_TAG:
//如果遇到river標籤結束,則把river對象添加進集合中
if (xmlParser.getName().equalsIgnoreCase(RIVER) && river != null) {
rivers.add(river);
river = null;
}
break;
default:break;
}
//如果xml沒有結束,則導航到下一個river節點
evtType=xmlParser.next();
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
return rivers;
}
運行結果與其他2個一樣: