Pull解析器的運行方式與?SAX?解析器相似。它提供了類似的事件,如:開始元素和結束元素事件,使用parser.next()可以進入下一個元素并觸發相應事件。跟SAX不同的是,?Pull解析器產生的事件是一個數字,而非方法,因此可以使用一個switch對感興趣的事件進行處理。當元素開始解析時,調用parser.nextText()方法可以獲取下一個Text類型節點的值。
下面我們通過Demo例子來介紹如何使用PULL機制來解析XML文件。先看下如下工程的目錄結構:

按以下步驟進行操作:
[1] 新建一個XML文件,命名為student.xml。同時把XML文件放置到assets目錄下。student.xml文件的內容如下:
~~~
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="20110806100">
<name>小明</name>
<age>22</age>
<sex>男</sex>
</student>
<student id="20110806101">
<name>小李</name>
<age>24</age>
<sex>男</sex>
</student>
<student id="20110806102">
<name>小麗</name>
<age>21</age>
<sex>女</sex>
</student>
</students>
~~~
[2] 根據XML文件中的節點目錄,創建一個相對應的實體類,來保存解析的相應信息。在包:com.andyidea.entity下新建Student.java類。
~~~
package com.andyidea.entity;
public class Student {
private String id;
private String name;
private int age;
private String sex;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
~~~
[3] 定義一個使用PULL解析XML文件的工具類:ParserByPULL.java。
~~~
package com.andyidea.util;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.util.Xml;
import com.andyidea.entity.Student;
public class ParserByPULL {
//采用XmlPullParser來解析XML文件
public static List<Student> getStudents(InputStream inStream) throws Throwable
{
List<Student> students = null;
Student mStudent = null;
//========創建XmlPullParser,有兩種方式=======
//方式一:使用工廠類XmlPullParserFactory
XmlPullParserFactory pullFactory = XmlPullParserFactory.newInstance();
XmlPullParser parser = pullFactory.newPullParser();
//方式二:使用Android提供的實用工具類android.util.Xml
//XmlPullParser parser = Xml.newPullParser();
//解析文件輸入流
parser.setInput(inStream, "UTF-8");
//產生第一個事件
int eventType = parser.getEventType();
//只要不是文檔結束事件,就一直循環
while(eventType!=XmlPullParser.END_DOCUMENT)
{
switch (eventType)
{
//觸發開始文檔事件
case XmlPullParser.START_DOCUMENT:
students = new ArrayList<Student>();
break;
//觸發開始元素事件
case XmlPullParser.START_TAG:
//獲取解析器當前指向的元素的名稱
String name = parser.getName();
if("student".equals(name))
{
//通過解析器獲取id的元素值,并設置student的id
mStudent = new Student();
mStudent.setId(parser.getAttributeValue(0));
}
if(mStudent!=null)
{
if("name".equals(name))
{
//獲取解析器當前指向元素的下一個文本節點的值
mStudent.setName(parser.nextText());
}
if("age".equals(name))
{
//獲取解析器當前指向元素的下一個文本節點的值
mStudent.setAge(new Short(parser.nextText()));
}
if("sex".equals(name))
{
//獲取解析器當前指向元素的下一個文本節點的值
mStudent.setSex(parser.nextText());
}
}
break;
//觸發結束元素事件
case XmlPullParser.END_TAG:
//
if("student".equals(parser.getName()))
{
students.add(mStudent);
mStudent = null;
}
break;
default:
break;
}
eventType = parser.next();
}
return students;
}
}
~~~
[4] 該Demo的入口類:MainActivity.java
~~~
package com.andyidea.xmlparser;
import java.io.InputStream;
import java.util.List;
import com.andyidea.entity.Student;
import com.andyidea.util.ParserByPULL;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
/**Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AssetManager asset = getAssets();
try {
InputStream input = asset.open("student.xml");
List<Student> list = ParserByPULL.getStudents(input);
for (Student stu : list) {
Log.e("StudentInfo","Person ID: " + stu.getId() + ","
+ stu.getName() + ", " + stu.getAge() + ", "
+ stu.getSex());
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
~~~
[5]最后我們運行程序看看結果如下:

以上黑色方框中的內容就是采用PULL方式解析的結果。