因为有些时候,应用的数据是采用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; @Override public 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 document while(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了。