使用PULL方式解析XML

在Java开发中大家常用SAX或者DOM解析XML文件,两者的特点也很明显:SAX基于事件驱动,速度快,占用内存少;DOM一次性把文件读入内存中,以树的方式操作XML数据更灵活。

PULL是第三种优秀的XML解析方式,其工作原理和SAX类似,也是基于事件驱动的,SAX和PULL比较如下:

(1)相同点:

SAX/PULL都是基于事件的解析器。

解析速度快,占用内存少。

(2)区别:

SAX可认为是“PUSH“推模式。解析器遇到事件源时会将数据推送给内容处理器(ContentHandler),SAX解析,一旦开始解析就要解析完成,中途不能退出。

PULL拉模式,主动从解析器中获取自己感兴趣的事件,感觉数据像是”拉“下来的,PULL式解析过程中(while循环里)解析完感兴趣的数据之后可以退出循环。

以Android代码为例演示一下PULL方式读写XML的过程:

例子XML文件test.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person id="23">
		<name>lisi</name>
		<age>30</age>
	</person>
	<person id="20">
		<name>zhangsan</name>
		<age>25</age>
	</person>
</persons>

先定义个javabean来对应上面的xml文件的内容:

package com.tony.domain;

public class Person {
	private int id;
	private String name;
	private int age;
	public Person(){
	}
	public Person(int id, String name, int age) {
		super();
		this.id = id;
		this.name = name;
		this.age = 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;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}

读取xml文件代码:

public static List<Person> getPersonsFromXML(InputStream xml) throws Exception{
		List<Person> persons = null;
		Person person = null;
//Android中获取PULL XML解析器,也可以使用XmlPullParserFactory.newInstance().newPullParser();
		XmlPullParser parser = Xml.newPullParser();
		parser.setInput(xml, "UTF-8");
		int event = parser.getEventType();
		while(event != XmlPullParser.END_DOCUMENT){//和SAX类似,PULL也使用startDocument和endDocument事件来判断文件的开始和结束
			switch(event){
			case XmlPullParser.START_DOCUMENT:
				persons = new ArrayList<Person>();
				break;
			case XmlPullParser.START_TAG://类似SAX的startElement事件,XML节点开始
				if("person".equals(parser.getName())){
					person = new Person();
					person.setId(Integer.parseInt(parser.getAttributeValue(0)));
				}
				if("name".equals(parser.getName())){
					person.setName(parser.nextText());
				}
				if("age".equals(parser.getName())){
					person.setAge(Integer.parseInt(parser.nextText()));
				}
				break;
			case XmlPullParser.END_TAG://类似SAX的endElement事件,XML节点结束
				if("pserson".equals(parser.getName())){
					persons.add(person);
					person = null;
				}
				break;
			}
			event = parser.next();//获取解析器中下一个事件
		}
		return persons;
	}

写xml代码:

public static void saveDataToXML(List<Person> persons, OutputStream os) throws Exception{
		XmlSerializer serializer = Xml.newSerializer();
		serializer.setOutput(os, "UTF-8");
		serializer.startDocument("UTF-8", true);//第二个参数设置该xml是否为standalone
		serializer.startTag(null, "persons");//第一个参数为命名空间
		for(Person person : persons){
			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();
		os.flush();
		os.close();
	}
通过代码我们看到PULL方式与SAX方式解析xml代码非常的类似,在对于只处理xml中部分内容情况下,PULL是非常好的选择。

你可能感兴趣的:(使用PULL方式解析XML)