Android开发系列(八):采用Pull解析器解析和生成XML内容

来源:互联网 发布:数据分析专员招聘 编辑:程序博客网 时间:2024/05/16 08:43

因为有些时候,应用的数据是采用XML文件的格式存放的,所以我们需要知道怎么从XML文件中读取这些数据

在Android中可以通过SAX、DOM、pull解析XML文件。

在本篇博文中主要介绍采用Pull解析器解析和生成XML内容。

介绍:在Android已经集成了Pull解析器,所以无需添加任何的jar文件。在Android中本身用到的各种xml文件,其内部也是采用Pull解析器进行解析的。


一、采用Pull解析器解析XML文件内容

首先,我们需要先建立一个Android Project项目,名称为:xml。默认生成MainActivity.java,在cn.itcast.xml包下,这个java文件里边的内容是自动生成的。


然后,我们在src目录下建立一个xml文件:person.xml:

<?xml version="1.0" encoding="UTF-8"?> <!-- 这个文件头是start document事件 --><persons><person id="1"><name>zhangsan</name><age>30</age></person><person id="2"><name>lisi</name><age>25</age></person></persons>
可以看出来这个xml文件存了两个person的信息。


接下来,我们需要建立一个javabean来反射这个xml文件,Person.java(注意这个bean中的属性要和xml中的对应,不然不能正确解析):

package cn.itcast.domain;public class Person {private Integer id;private String name;private Integer age;@Overridepublic String toString() {return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}
在这个java文件中我们定义了三个属性:id、name、age,并生成了一个toString()的方法


在实体类建好之后,我们需要写业务层的类了,PersonService.java:

package cn.itcast.service;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import cn.itcast.domain.*;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlPullParserFactory;import android.util.Xml;public class PersonService {public static List<Person> getPersons(InputStream xml) throws Exception{List<Person> persons = null;Person person  = null;//得到解析器/*这个方法和下边功能相同,可以得到解析器:XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser();*/XmlPullParser pullParser = Xml.newPullParser();pullParser.setInput(xml,"UTF-8");//为Pull解析器设置要解析的XML数据int event = pullParser.getEventType(); //产生第一个事件:start documentwhile(event != XmlPullParser.END_DOCUMENT){switch (event) { //对事件进行判断case XmlPullParser.START_DOCUMENT:persons = new ArrayList<Person>();break;case XmlPullParser.START_TAG:if("person".equals(pullParser.getName())){int id = new Integer(pullParser.getAttributeValue(0));person = new Person();person.setId(id);}if("name".equals(pullParser.getName())){String name = pullParser.nextText();person.setName(name);}if("age".equals(pullParser.getName())){int age = new Integer(pullParser.nextText());person.setAge(age);}break;case XmlPullParser.END_TAG:if("person".equals(pullParser.getName())){persons.add(person);person = null;}break;}event = pullParser.next();}return persons;}}
这段代码比较麻烦,我们接下来具体分析一下:

XmlPullParser pullParser = Xml.newPullParser();这段代码是为了得到一个Pull解析器,另外:XmlPullParser pullParser = XmlPullParserFactory.newInstance().newPullParser();也可以得到Pull解析器。

pullParser.setInput(xml,"UTF-8");用来设置要解析的xml文件的编码格式,这里是“UTF-8”

因为Pull解析器是一个遍历文档的过程,所以要从<?xml version="1.0" encoding="UTF-8"?>这个start document事件开始,一直到</persons>结束。

int event = pullParser.getEventType();在这个时候,文档被初始化,这里会获得文档的start document,就是START_DOCUMENT事件。

然后,是一个while循环,限制条件是event != XmlPullParser.END_DOCUMENT,即当前遍历的节点没有达到结尾,就会执行while循环。

在while循环里边是一个switch()控制语句,用来控制当前选中的是哪个节点,里边有三个case:

case XmlPullParser.START_DOCUMENT:满足START_DOCUMENT事件(就是xml文件的开头)

case XmlPullParser.START_TAG:满足START_TAG事件(就是xml元素节点的开头:比如本篇中的<person>)

case XmlPullParser.END_TAG::满足END_TAG事件(就是xml元素节点的结尾:比如本篇中的</person>)

在第二个case中,我们做了三个判断:

if("person".equals(pullParser.getName())):如果到达的是person元素节点,则把id赋给person

if("name".equals(pullParser.getName())):如果到达的是name元素节点,则把name赋给person

if("age".equals(pullParser.getName())):如果到达的是age元素节点,则把age赋给person


注意,在每一次switch()控制语句结束之后,会有一个event = pullParser.next(),这句话的意思是把Pull解析器指针指向下个节点。



以上,我们就把Pull解析器完成了,然后我们编写一个测试类:

注意首先配置AndroidManfiest.xml引入测试的语法,这里不多说了。

编写PersonServiceTest.java,放在cn.itcast.test文件目录下:

package cn.itcast.test;import java.io.InputStream;import java.util.List;import cn.itcast.domain.Person;import cn.itcast.service.PersonService;import android.test.AndroidTestCase;import android.util.Log;public class PersonServiceTest  extends AndroidTestCase{private static final String TAG = "PersonServiceTest";public void testPersons() throws Exception{//通过getClassLoader()方法得到src目录下person.xml文件的输入流InputStream xml = this.getClass().getClassLoader().getResourceAsStream("person.xml");List<Person> persons = PersonService.getPersons(xml);for(Person person : persons){Log.i(TAG, person.toString());}}}
然后,我们在LogCat页面中添加一个过滤器:

就可以在LogCat页面打印出来persons了。


二、采用Pull解析器生成XML内容

我们要在PersonService.java中定义一个save()方法用来生成XML文件:

/** * 保存数据 * @param persons 数据 * @param out 输出方向 * @throws Exception */public static void save(List<Person> persons, OutputStream out) throws Exception{XmlSerializer serializer = Xml.newSerializer(); //得到实例化器serializer.setOutput(out, "UTF-8"); //设置输出流编码格式serializer.startDocument("UTF-8", true);//设置START_DOCUMENT,就是xml的开头serializer.startTag(null, "persons"); //开始第一个persons标签for(Person person : persons){serializer.startTag(null, "person");serializer.attribute(null, "id", person.getId().toString());serializer.startTag(null, "name");serializer.text(person.getName());serializer.endTag(null, "name");serializer.startTag(null, "age");serializer.text(person.getAge().toString());serializer.endTag(null, "age");serializer.endTag(null, "person");}serializer.endTag(null, "persons");serializer.endDocument();out.flush();out.close();}
然后,我们在测试类PersonServiceTest.java中加入一个方法:

public void testSave() throws Exception{List<Person> persons = new ArrayList<Person>();persons.add(new Person(43, "zhangxx",80));persons.add(new Person(24, "lisi",80));persons.add(new Person(12, "wangwu",80));//放在/files目录下File xmlFile = new File(getContext().getFilesDir(),"itcast.xml");//打开输出流FileOutputStream outStream = new FileOutputStream(xmlFile);PersonService.save(persons , outStream); //调用save()方法生成xml文件}
我们就可以在files文件目录下生成一个itcast.xml文件了










1 0