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();
- //方式三:使用Resources的getXml()方法返回XmlResourceParser对象
- //XmlResourceParser Parser=getResources().getXml(R.xml.student);
- //用着三种中的任一种,只需把标签开头的类变一下即可。以第三个为例只需把XmlPullParser.END_DOCUMENT改为XmlResourceParser.END_DOCUMENT所 //有标签都这么改即可
-
- //解析文件输入流
- 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]最后我们运行程序看看结果如下: