转载博文1:http://blog.csdn.net/wangkuifeng0118/article/details/7313241
XmlPull和Sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此Xmlpull和 Sax都比较节约内存资源,不会象Dom那样要把所有节点以对橡树的形式展现在内存中。 但Xmlpull比Sax更简明,而且不需要扫描完整个流。
下面来看一个pull解析xml的例子:
student.xml:
1 <?xml version="1.0" encoding="utf-8"?> 2 <root> 3 <student id="1" group="1"> 4 <name>张三</name> 5 <sex>男</sex> 6 <age>18</age> 7 <email>zhangsan@163.com</email> 8 <birthday>1987-06-08</birthday> 9 <memo>好学生</memo> 10 </student> 11 <student id="2" group="2"> 12 <name>李四</name> 13 <sex>女</sex> 14 <age>18</age> 15 <email>lisi@163.com</email> 16 <birthday>1987-06-08</birthday> 17 <memo>好学生</memo> 18 </student> 19 <student id="3" group="3"> 20 <name>小王</name> 21 <sex>男</sex> 22 <age>18</age> 23 <email>xiaowang@163.com</email> 24 <birthday>1987-06-08</birthday> 25 <memo>好学生</memo> 26 </student> 27 <student id="4" group="4"> 28 <name>小张</name> 29 <sex>男</sex> 30 <age>18</age> 31 <email>xiaozhang@163.com</email> 32 <birthday>1987-06-08</birthday> 33 <memo>好学生</memo> 34 </student> 35 <student id="5" group="5"> 36 <name>小明</name> 37 <sex>男</sex> 38 <age>18</age> 39 <email>xiaoming@163.com</email> 40 <birthday>1987-06-08</birthday> 41 <memo>好学生</memo> 42 </student> 43 </root>
对应的bean:
1 public class Student { 2 3 private int id; 4 private int group; 5 private String name; 6 private String sex; 7 private int age; 8 private String email; 9 private String memo; 10 private String birthday; 11 public int getId() { 12 return id; 13 } 14 public void setId(int id) { 15 this.id = id; 16 } 17 public int getGroup() { 18 return group; 19 } 20 public void setGroup(int group) { 21 this.group = group; 22 } 23 public String getName() { 24 return name; 25 } 26 public void setName(String name) { 27 this.name = name; 28 } 29 public String getSex() { 30 return sex; 31 } 32 public void setSex(String sex) { 33 this.sex = sex; 34 } 35 public int getAge() { 36 return age; 37 } 38 public void setAge(int age) { 39 this.age = age; 40 } 41 public String getEmail() { 42 return email; 43 } 44 public void setEmail(String email) { 45 this.email = email; 46 } 47 public String getMemo() { 48 return memo; 49 } 50 public void setMemo(String memo) { 51 this.memo = memo; 52 } 53 public String getBirthday() { 54 return birthday; 55 } 56 public void setBirthday(String birthday) { 57 this.birthday = birthday; 58 } 59 60 }
主要的解析和现实类:
1 import java.io.InputStream; 2 import java.util.ArrayList; 3 import java.util.List; 4 5 import org.xmlpull.v1.XmlPullParser; 6 import org.xmlpull.v1.XmlPullParserFactory; 7 8 import android.app.Activity; 9 import android.os.Bundle; 10 import android.os.Handler; 11 import android.os.Message; 12 import android.view.ViewGroup.LayoutParams; 13 import android.widget.LinearLayout; 14 15 import android.widget.TextView; 16 17 public class PullActivity extends Activity implements Runnable{ 18 19 private TextView pullTextView ; 20 private LinearLayout layout; 21 private Handler handler=new Handler(){ 22 public void handleMessage(android.os.Message msg) { 23 List<Student> lists=(List<Student>) msg.obj; 24 for(int i=0;i<lists.size();i++){ 25 Student student=lists.get(i); 26 StringBuffer sb=new StringBuffer(); 27 sb.append(student.getId()+" ").append(student.getName()+" ") 28 .append(student.getAge()+" ").append(student.getSex()+" ").append(student.getBirthday()+" ") 29 .append(student.getEmail()+" ").append(student.getGroup()+" "); 30 TextView txt=new TextView(getApplicationContext()); 31 txt.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 32 txt.setText(sb.toString()); 33 layout.addView(txt); 34 } 35 }; 36 }; 37 @Override 38 protected void onCreate(Bundle savedInstanceState) { 39 // TODO Auto-generated method stub 40 super.onCreate(savedInstanceState); 41 setContentView(R.layout.pull); 42 43 pullTextView=(TextView) this.findViewById(R.id.pullTextView); 44 layout=(LinearLayout) this.findViewById(R.id.layout); 45 new Thread(this).start(); 46 47 48 49 } 50 //pull解析xml 51 public List<Student> pullParseXml(){ 52 List<Student> lists=null; 53 Student student=null; 54 55 try { 56 XmlPullParserFactory factory=XmlPullParserFactory.newInstance(); 57 //获取XmlPullParser实例 58 XmlPullParser pullParser=factory.newPullParser(); 59 InputStream in=this.getClass().getClassLoader().getResourceAsStream("student.xml"); 60 pullParser.setInput(in, "UTF-8"); 61 //开始 62 int eventType=pullParser.getEventType(); 63 64 while(eventType!=XmlPullParser.END_DOCUMENT){ 65 String nodeName=pullParser.getName(); 66 switch (eventType) { 67 //文档开始 68 case XmlPullParser.START_DOCUMENT: 69 lists=new ArrayList<Student>(); 70 break; 71 72 //开始节点 73 case XmlPullParser.START_TAG: 74 if("student".equals(nodeName)){ 75 student=new Student(); 76 student.setId(Integer.parseInt(pullParser.getAttributeValue(0))); 77 student.setGroup(Integer.parseInt(pullParser.getAttributeValue(1))); 78 }else if("name".equals(nodeName)){ 79 student.setName(pullParser.nextText()); 80 }else if("sex".equals(nodeName)){ 81 student.setSex(pullParser.nextText()); 82 }else if("age".equals(nodeName)){ 83 student.setAge(Integer.parseInt(pullParser.nextText())); 84 }else if("email".equals(nodeName)){ 85 student.setEmail(pullParser.nextText()); 86 }else if("birthday".equals(nodeName)){ 87 student.setBirthday(pullParser.nextText()); 88 }else if("memo".equals(nodeName)){ 89 student.setMemo(pullParser.nextText()); 90 } 91 break; 92 //结束节点 93 case XmlPullParser.END_TAG: 94 if("student".equals(nodeName)){ 95 lists.add(student); 96 student=null; 97 } 98 break; 99 default: 100 break; 101 } 102 // 手动的触发下一个事件 103 eventType=pullParser.next(); 104 } 105 } catch (Exception e) { 106 // TODO Auto-generated catch block 107 e.printStackTrace(); 108 } 109 return lists; 110 111 } 112 @Override 113 public void run() { 114 // TODO Auto-generated method stub 115 List<Student> lists=pullParseXml(); 116 Message msg=handler.obtainMessage(); 117 msg.obj=lists; 118 handler.sendMessage(msg); 119 } 120 }
注意xml中的<?xml version="1.0" encoding="utf-8"?> 这句话要顶格显示,不要留空隙,附则错了很难调试的。
解析后效果:
今天我们一起通过一个小例子来学习一下使用PULL解析器解析XML文件。
(1)首先我们放一个文件名为beauties.xml的XML文件到assets目录下,文件内容如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <beauties>
- <beauty>
- <name>范冰冰</name>
- <age>28</age>
- </beauty>
- <beauty>
- <name>杨幂</name>
- <age>23</age>
- </beauty>
- </beauties>
然后在src目录下写一个与XML中节点(Node)相对应的类Beauty,其内容如下:
- package com.pulltest;
- 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;
- }
- @Override
- public String toString() {
- return "美女资料 [年龄=" + age + ", 姓名=" + name + "]";
- }
- }
(2)在src目录下写一个接口IBeautyParser,其内容如下:
- package com.pulltest;
- import java.io.InputStream;
- import java.util.List;
- public interface IBeautyParser {
- /**
- *
- * 解析输入流,获取Beauty列表
- * @param is
- * @return
- * @throws Exception
- */
- public List<Beauty> parse(InputStream is) throws Exception;
- /**
- *
- * 序列化Beauty对象集合,得到XML形式的字符串
- * @param beauties
- * @return
- * @throws Exception
- */
- public String serialize(List<Beauty> beauties) throws Exception;
- }
在src目录下写一个上面接口的实现类BeautyParserImpl,其内容如下,代码已经详细注释:
- package com.pulltest;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.List;
- import org.xmlpull.v1.XmlPullParser;
- import android.util.Xml;
- public class BeautyParserImpl implements IBeautyParser{
- @Override
- public List<Beauty> parse(InputStream is) throws Exception {
- List<Beauty> mList = null;
- Beauty beauty = null;
- // 由android.util.Xml创建一个XmlPullParser实例
- XmlPullParser xpp = Xml.newPullParser();
- // 设置输入流 并指明编码方式
- xpp.setInput(is,"UTF-8");
- // 产生第一个事件
- int eventType = xpp.getEventType();
- while (eventType != XmlPullParser.END_DOCUMENT){
- switch (eventType) {
- // 判断当前事件是否为文档开始事件
- case XmlPullParser.START_DOCUMENT:
- mList = new ArrayList<Beauty>(); // 初始化books集合
- break;
- // 判断当前事件是否为标签元素开始事件
- case XmlPullParser.START_TAG:
- if (xpp.getName().equals("beauty")) { // 判断开始标签元素是否是book
- beauty = new Beauty();
- } else if (xpp.getName().equals("name")) {
- eventType = xpp.next();//让解析器指向name属性的值
- // 得到name标签的属性值,并设置beauty的name
- beauty.setName(xpp.getText());
- } else if (xpp.getName().equals("age")) { // 判断开始标签元素是否是book
- eventType = xpp.next();//让解析器指向age属性的值
- // 得到age标签的属性值,并设置beauty的age
- beauty.setAge(xpp.getText());
- }
- break;
- // 判断当前事件是否为标签元素结束事件
- case XmlPullParser.END_TAG:
- if (xpp.getName().equals("beauty")) { // 判断结束标签元素是否是book
- mList.add(beauty); // 将book添加到books集合
- beauty = null;
- }
- break;
- }
- // 进入下一个元素并触发相应事件
- eventType = xpp.next();
- }
- return mList;
- }
- @Override
- public String serialize(List<Beauty> beauties) throws Exception {
- // TODO Auto-generated method stub
- return null;
- }
- }
(3) 在layout目录下新建一个布局文件pulltest.xml,其内容如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/textView"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
在src目录下的Activity内容如下:
- package com.pulltest;
- import java.io.InputStream;
- import java.util.List;
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.TextView;
- import com.example.pulltest.R;
- public class PullTestActivity extends Activity{
- //装载Beauty类型的链表,其内容由XML文件解析得到
- private List<Beauty> beautyList;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.pulltest);
- try {
- //通过assertmanager的open方法获取到beauties.xml文件的输入流
- InputStream is = this.getAssets().open("beauties.xml");
- //初始化自定义的实现类BeautyParserImpl
- BeautyParserImpl pbp = new BeautyParserImpl();
- //调用pbp的parse()方法,将输入流传进去解析,返回的链表结果赋给beautyList
- beautyList = pbp.parse(is);
- } catch (Exception e) {
- e.printStackTrace();
- }
- setupViews();
- }
- /**
- * 将数据显示到手机界面上
- */
- private void setupViews(){
- String result = "";
- for (Beauty b : beautyList) {
- result += b.toString();
- }
- TextView textView = (TextView) findViewById(R.id.textView);
- textView.setText(result);
- }
- }
我们右键运行一下android project,结果截图如下:
完整的实例代码下载地址: