1.Pull解析器概述
Pull解析和Sax解析很相似,都是轻量级的解析xml工具,在Android的内核中已经嵌入了Pull工具包,所以我们不需要再添加第三方jar包。Pull解析xml文件过程中会触发相应的事件,默认解析完一个标签则不继续往下解析,只有调用next方法,才继续往下解析,根据解析器的getEventType来获得解析对象的类型。
2.Pull解析数据
- /*
- * MainActivity.java
- */
- package com.baidu.parsexmltest;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import android.os.Bundle;
- import android.app.ListActivity;
- import android.widget.ListView;
- import android.widget.SimpleAdapter;
- import android.widget.Toast;
- public class MainActivity extends ListActivity {
- private ListView listView;
- private List<Person> persons;
- private List<Map<String, String>> list;
- private Map<String, String> map;
- private InputStream is;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- listView = this.getListView(); //得到ListView控件,由于继承了ListActivity可以直接得到
- list = new ArrayList<Map<String,String>>();
- read(); //读取xml文件
- listView.setAdapter(new SimpleAdapter(this, list, R.layout.item,
- new String[]{"id", "name", "age"},
- new int[]{R.id.id, R.id.name, R.id.age}));
- save(); //保存xml文件
- }
- /**
- * 保存xml文件
- */
- public void save() {
- File file = new File(this.getApplication().getFilesDir(),
- "personNew.xml"); //定义file对象,路径为/data/dara/<package name>/files/personNew.xml
- try {
- FileOutputStream fos = new FileOutputStream(file);
- XmlTool.save(persons, fos); //主要保存xml方法
- Toast.makeText(this, R.string.success, Toast.LENGTH_SHORT).show();//保存成功提示
- return ;
- } catch (Exception e) {
- e.printStackTrace();
- }
- Toast.makeText(this, R.string.fail, Toast.LENGTH_SHORT).show(); //保存失败提示
- }
- /*
- * 读取xml文件
- */
- public void read() {
- try {
- is = this.getAssets().open("persons.xml"); //打开assets目录中保存的xml文件
- persons = new XmlTool().parser(is); //主要读取xml文件方法
- for (Person p : persons) {
- map = new HashMap<String, String>();
- map.put("id", Integer.toString(p.getId()));
- map.put("name", p.getName());
- map.put("age", Integer.toString(p.getAge()));
- list.add(map);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- /**
- * XmlTool.java
- * 解析xml文件盒保存xml主要工具
- */
- package com.baidu.parsexmltest;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.List;
- import org.xmlpull.v1.XmlPullParser;
- import org.xmlpull.v1.XmlSerializer;
- import android.util.Xml;
- public class XmlTool {
- private List<Person> persons;
- Person person = null;
- /**
- * 解析xml文件
- * @param in 字节输入流
- * @return 返回list集合
- * @throws Exception
- */
- public List<Person> parser(InputStream in) throws Exception {
- /*
- * XmlPullParser解析xml文件,读完相应的标签后会触发相应的事件!
- * 对一个xml文件读取存在5种类型
- * <?xml version="1.0" encoding="utf-8"?> //StartDocument
- * <person> //StartTag
- * info //Text
- * </person> //EndTag
- * //EndDocument
- * 默认读完一个标签后,不再继续往下读取,只有执行解析器的next方法,才会继续往下执行解析操作
- */
- // 1.创建一个xml解析的工厂
- XmlPullParserFactory factory=XmlPullParserFactory.newInstance();
- // 2.获得xml解析类的引用
- XmlPullParser parser = factory.newPullParser();
- // 3.设定解析器读取的字节流对象,含有编码方式
- parser.setInput(in, "UTF-8");
- // 4.得到解析返回的事件类型
- int type = parser.getEventType();
- // 5.根据事件类型,进行选择操作
- while(type != XmlPullParser.END_DOCUMENT){ //判断没有到文件的末尾就进行循环操作
- switch (type) {
- case XmlPullParser.START_DOCUMENT: //主要完成初始化动作
- persons = new ArrayList<Person>();
- break;
- case XmlPullParser.START_TAG: //开始标签,完成数据操作
- if("person".equals(parser.getName())){
- person = new Person();
- person.setId(Integer.parseInt(parser.getAttributeValue(0))); //这里由于id直接跟person在一个标签里面写着,所用getAttributeValue(0)表示获得第一个属性的值。例子<person id=1>
- } else if("name".equals(parser.getName())){
- person.setName(parser.nextText()); //可以直接获得文本标签信息
- } else if("age".equals(parser.getName())){
- person.setAge(Integer.parseInt(parser.nextText()));
- }
- break;
- case XmlPullParser.END_TAG: //结束标签
- if("person".equals(parser.getName())){
- persons.add(person);
- }
- break;
- }
- type = parser.next(); //下一个标签,默认读完该标签不再继续往下执行读取操作
- }
- return persons;
- }
- /**
- * 保存xml文件
- * @param list list集合对象
- * @param fos 输出流对象
- * @throws Exception
- */
- public static void save(List<Person> list, FileOutputStream fos) throws Exception{
- // 1.定义Xml序列器
- XmlSerializer serializer = Xml.newSerializer();
- // 2.为该序列器对象设定输出流
- serializer.setOutput(fos, "UTF-8");
- // 3.xml写入信息
- serializer.startDocument("UTF-8", true); //能否单独存在
- serializer.startTag(null, "persons"); //第一个参数为命名空间
- for(Person person:list){
- serializer.startTag(null, "person");
- serializer.attribute(null, "id", Integer.toString(person.getId()));//赋予属性信息
- serializer.startTag(null, "name");
- serializer.text(person.getName());
- serializer.endTag(null, "name");
- serializer.startTag(null, "age");
- serializer.text(Integer.toString(person.getAge()));
- serializer.endTag(null, "age");
- serializer.endTag(null, "person");
- }
- serializer.endTag(null, "persons");
- serializer.endDocument(); //文档结束
- fos.flush();
- fos.close();
- return;
- }
- }
- /*
- * Person.java
- */
- package com.baidu.parsexmltest;
- public class Person {
- private int id;
- private String name;
- private int age;
- public int getId() {
- return id;
- }
- public void setId(int 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;
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <!-- ListView布局 item.xml -->
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="40sp"
- android:orientation="horizontal" >
- <TextView android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center_vertical"
- android:textSize="16sp"
- android:id="@+id/id"/>
- <TextView android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:layout_weight="1"
- android:textSize="16sp"
- android:id="@+id/name"/>
- <TextView android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="center_vertical"
- android:layout_weight="1"
- android:textSize="16sp"
- android:id="@+id/age"/>
- </LinearLayout>
3.更新xml文件
如果只是简单的生成xml文件,则可以使用pull方式的Xml.newSerializer()去生成一个xml文档很方便,但是对其修改很麻烦。如果只为修改xml文件,可以参考dom解析方式,添加或者移除一个节点。