Pull解析和Sax解析很相似,都是轻量级的解析xml工具,在Android的内核中已经嵌入了Pull工具包,所以我们不需要再添加第三方jar包。Pull解析xml文件过程中会触发相应的事件,默认解析完一个标签则不继续往下解析,只有调用next方法,才继续往下解析,根据解析器的getEventType来获得解析对象的类型。
/* * 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.定义解析器 XmlPullParser parser = Xml.newPullParser(); // 2.设定解析器读取的字节流对象,含有编码方式 parser.setInput(in, "UTF-8"); // 3.得到解析返回的事件类型 int type = parser.getEventType(); // 4.根据事件类型,进行选择操作 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))); } 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>
如果只是简单的生成xml文件,则可以使用pull方式的Xml.newSerializer()去生成一个xml文档很方便,但是对其修改很麻烦。如果只为修改xml文件,可以参考dom解析方式,添加或者移除一个节点。