Android内置的Pull解析器XmlPull和Sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此Xmlpull和 Sax都比较节约内存资源,不会象Dom那样要把所有节点以对橡树的形式展现在内存中。 但Xmlpull比Sax更简明,而且不需要扫描完整个流。
对象的种类
Document 整个xml文档对象
Element 文档中的标签对象
Atritube 标签中的属性对象
Text 标签体的内容的对象
Common 注释对象
常用事件
START_DOCUMENT 文档开始
END_DOCUMENT 文档结束
START_TAG 元素开始
END_TAG 元素结束
Dom解析xml是先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。要是数据过大,手机配置不行可能会死机。
SAX解析是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
Pull解析器和SAX解析器很相似,但SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。
Pull解析
与Sax一样.都属于事件驱动的解析方式.
相比Sax解析过程更加灵活.
sax一旦开始解析就是从头读到尾.不解析完整个文档不会停
pull解析较为灵活.是以事件为单位.手动向下继续. 如果获得到我们要找的内容. 可以停止继续解析.
示例一:
1、app-new-Folder-Assets Folder 新建assets文件夹,并新建student.xml文件。
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="1001">
<stuno>1001</stuno>
<name>张三</name>
<sex>男</sex>
<grade>Java一班</grade>
</student>
<student id="1002">
<stuno>1002</stuno>
<name>李四</name>
<sex>女</sex>
<grade>Java二班</grade>
</student>
<student id="1003">
<stuno>1003</stuno>
<name>小二</name>
<sex>男</sex>
<grade>Java三班</grade>
</student>
<student id="1004">
<stuno>1004</stuno>
<name>小蜡</name>
<sex>女</sex>
<grade>Java四班</grade>
</student>
</students>
2、获取xml文件流,并使用pull解析。
package com.example.administrator.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InputStream inputStream = null;
try {
inputStream = getAssets().open("student.xml");
} catch (IOException e) {
e.printStackTrace();
}
parseXMLWithPull(inputStream);
}
private void parseXMLWithPull(InputStream inputStream) {
try {
// 创建一个解析工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 由工厂创建一个解析器对象
XmlPullParser parser = factory.newPullParser();
// 打开xml文档对应的输入流,填写xml文档的路径
parser.setInput(inputStream, "UTF-8");
// 获得事件类型
int eventType = parser.getEventType();
System.out.println(eventType == XmlPullParser.START_DOCUMENT);
do {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
System.out.println("读取开始,开始文档!");
break;
case XmlPullParser.START_TAG:
String tagName = parser.getName();
if (tagName.equals("student")) {
System.out.println("读取进度-开始标签:" + parser.getName() + ":" +
parser.getAttributeName(0) + ":"
+ parser.getAttributeValue(0));
} else if (tagName.equals("stuno")) {
System.out.println("读取进度-学号:" + parser.nextText());
} else if (tagName.equals("name")) {
System.out.println("读取进度-姓名:" + parser.nextText());
} else if (tagName.equals("sex")) {
System.out.println("读取进度-性别:" + parser.nextText());
} else if (tagName.equals("grade")) {
System.out.println("读取进度-班级:" + parser.nextText());
} else if (tagName.equals("students")) {
System.out.println("读取开始-开始根目录:" + parser.getName());
}
break;
case XmlPullParser.END_TAG:
if (parser.getName().equals("student")) {
System.out.println("读取进度-结束标签:" + parser.getName());
} else if (parser.getName().equals("students")) {
System.out.println("读取完成-结束根目录:" + parser.getName());
}
break;
}
// 读取下一个节点
eventType = parser.next();
} while (eventType != XmlPullParser.END_DOCUMENT);
System.out.println("读取完成,文档结束!");
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
3、结果:
I/System.out: true
I/System.out: 读取开始,开始文档!
I/System.out: 读取开始-开始根目录:students
I/System.out: 读取进度-开始标签:student:id:1001
I/System.out: 读取进度-学号:1001
I/System.out: 读取进度-姓名:张三
I/System.out: 读取进度-性别:男
I/System.out: 读取进度-班级:Java一班
I/System.out: 读取进度-结束标签:student
I/System.out: 读取进度-开始标签:student:id:1002
I/System.out: 读取进度-学号:1002
I/System.out: 读取进度-姓名:李四
I/System.out: 读取进度-性别:女
I/System.out: 读取进度-班级:Java二班
I/System.out: 读取进度-结束标签:student
I/System.out: 读取进度-开始标签:student:id:1003
I/System.out: 读取进度-学号:1003
I/System.out: 读取进度-姓名:小二
I/System.out: 读取进度-性别:男
I/System.out: 读取进度-班级:Java三班
I/System.out: 读取进度-结束标签:student
I/System.out: 读取进度-开始标签:student:id:1004
I/System.out: 读取进度-学号:1004
I/System.out: 读取进度-姓名:小蜡
I/System.out: 读取进度-性别:女
I/System.out: 读取进度-班级:Java四班
I/System.out: 读取进度-结束标签:student
I/System.out: 读取完成-结束根目录:students
I/System.out: 读取完成,文档结束!
参考:
PULL解析XML文件
示例二:
1、建立assets文件夹,并建立文件student1.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<student id="1" group="1">
<name>张三</name>
<sex>男</sex>
<age>18</age>
<email>zhangsan@163.com</email>
<birthday>1987-06-08</birthday>
<memo>好学生</memo>
</student>
<student id="2" group="2">
<name>李四</name>
<sex>女</sex>
<age>18</age>
<email>lisi@163.com</email>
<birthday>1987-06-08</birthday>
<memo>好学生</memo>
</student>
<student id="3" group="3">
<name>小王</name>
<sex>男</sex>
<age>18</age>
<email>xiaowang@163.com</email>
<birthday>1987-06-08</birthday>
<memo>好学生</memo>
</student>
<student id="4" group="4">
<name>小张</name>
<sex>男</sex>
<age>18</age>
<email>xiaozhang@163.com</email>
<birthday>1987-06-08</birthday>
<memo>好学生</memo>
</student>
<student id="5" group="5">
<name>小明</name>
<sex>男</sex>
<age>18</age>
<email>xiaoming@163.com</email>
<birthday>1987-06-08</birthday>
<memo>好学生</memo>
</student>
</root>
2、建立Student实体类:
package com.example.administrator.myapplication;
/**
* Created by Administrator on 2017/5/11.
*/
public class Student {
private int id;
private int group;
private String name;
private String sex;
private int age;
private String email;
private String memo;
private String birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getGroup() {
return group;
}
public void setGroup(int group) {
this.group = group;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}
3、获取文件流,使用pull解析xml
package com.example.administrator.myapplication;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
List<Student> lists = (List<Student>) msg.obj;
for (int i = 0; i < lists.size(); i++) {
Student student = lists.get(i);
StringBuffer sb = new StringBuffer();
sb.append(student.getId() + " ")
.append(student.getName() + " ")
.append(student.getAge() + " ")
.append(student.getSex() + " ")
.append(student.getBirthday() + " ")
.append(student.getEmail() + " ")
.append(student.getGroup() + " ");
Log.e("MainActivity", "打印==" + sb.toString());
}
}
;
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InputStream inputStream = null;
try {
inputStream = getAssets().open("student1.xml");
} catch (IOException e) {
e.printStackTrace();
}
final InputStream finalInputStream = inputStream;
new Thread(new Runnable() {
@Override
public void run() {
List<Student> lists = pullParseXml(finalInputStream);
Message msg = handler.obtainMessage();
msg.obj = lists;
handler.sendMessage(msg);
}
}).start();
}
//pull解析xml
public List<Student> pullParseXml(InputStream in) {
List<Student> lists = null;
Student student = null;
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser pullParser = factory.newPullParser();
pullParser.setInput(in, "UTF-8");
//开始
int eventType = pullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = pullParser.getName();
switch (eventType) {
//文档开始
case XmlPullParser.START_DOCUMENT:
lists = new ArrayList<Student>();
break;
//开始节点
case XmlPullParser.START_TAG:
if ("student".equals(nodeName)) {
student = new Student();
student.setId(Integer.parseInt(pullParser.getAttributeValue(0)));
student.setGroup(Integer.parseInt(pullParser.getAttributeValue(1)));
} else if ("name".equals(nodeName)) {
student.setName(pullParser.nextText());
} else if ("sex".equals(nodeName)) {
student.setSex(pullParser.nextText());
} else if ("age".equals(nodeName)) {
student.setAge(Integer.parseInt(pullParser.nextText()));
} else if ("email".equals(nodeName)) {
student.setEmail(pullParser.nextText());
} else if ("birthday".equals(nodeName)) {
student.setBirthday(pullParser.nextText());
} else if ("memo".equals(nodeName)) {
student.setMemo(pullParser.nextText());
}
break;
//结束节点
case XmlPullParser.END_TAG:
if ("student".equals(nodeName)) {
lists.add(student);
student = null;
}
break;
default:
break;
}
// 手动的触发下一个事件
eventType = pullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
return lists;
}
}
结果:
打印==1 张三 18 男 1987-06-08 zhangsan@163.com 1
打印==2 李四 18 女 1987-06-08 lisi@163.com 2
打印==3 小王 18 男 1987-06-08 xiaowang@163.com 3
打印==4 小张 18 男 1987-06-08 xiaozhang@163.com 4
打印==5 小明 18 男 1987-06-08 xiaoming@163.com 5
参考: