Android中使用Pull解析器解析xml文件+进行简单的单元测试

Android中使用Pull解析器解析xml文件+进行简单的单元测试


我来给大家介绍Android用得最多的一种解析xml数据的技术:Pull解析器解析,之前介绍过Java中两种解析xml的技术:Dom解析和SAX解析,Dom比较适合小数据量的解析,然而SAX适合大数据量的解析工作,但比较复杂。第三种解析技术Pull解析,是一种比前面两种方法更加简单的解析技术,更加符合面向对象的思想,因为这是按照我们正常的思考方式进行解析,下面来看看利用这种解析器的实现过程。

首先我们需要知道这个xml文件的内容:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person id="23">
		<name>liming</name>
		<age>30</age>
	</person>
	<person id="20">
		<name>zhangxiaoxiao</name>
		<age>25</age>
	</person>
</persons>

这是最典型的xml格式的数据,它有以下几个组成部分
1. START_DOCUMENT--- 文档的开始部分
<?xml version="1.0" encoding="UTF-8"?>
2. START_TAG ---开始标签
<persons>
3. END_TAG ---结束标签
</persons>
4. END_DOCUMENT ---文档结束部分


知道文档的组织结构之后,就可以往这个方向去思考怎么解析数据了
定义以下方法
/**
	 * 获取数据
	 * @param xml
	 * @return
	 * @throws Exception
	 */
	public static List<Person> getPersons(InputStream xml) throws Exception {
		List<Person> persons = null;
		Person person = null;
		XmlPullParser pullParser = Xml.newPullParser();	// 获取Pull解析器
		pullParser.setInput(xml, "UTF-8");//为Pull解析器设置要解析的XML数据
		int event = pullParser.getEventType();	//获取第一次解析所产生的事件
		while (event != pullParser.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;
	}


解析出来的结果保存到一个集合里,我们通过集合就可把数据取出来了。

因为已经知道xml文档结构,我们当然也可以将数据保存问xml格式的数据
这里需要用到Android为我们提供的xml序列化器,首先需要获得这个序列号器,然后分别设置各个标签的内容,具体实现如下:
/**
	 * 保存数据
	 * @param persons
	 * @param out
	 * @throws Exception
	 */
	public static void save(List<Person> persons, OutputStream out) throws Exception {
		XmlSerializer serializer = Xml.newSerializer();	//得到Xml序列化器
		serializer.setOutput(out, "UTF-8");
		serializer.startDocument("UTF-8", true);
		serializer.startTag(null, "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();
	}
	

这个方法需要传入一个集合,和一个输出流;方法调用结束后,就会把文件输出到指定目录下。


介绍完Pull解析和输出xml文件的方法之后,小巫最近学到了如何在Android下进行简单的单元测试,是一个很重要的技能。
要进行单元测试需要进行以下几个步骤:
1.  在AndroidMenifest.xml文件中进行配置,完整的配置文件如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.wwj.xml"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <uses-library android:name="android.test.runner" />
    </application>
<instrumentation android:name="android.test.InstrumentationTestRunner"
  android:targetPackage="org.wwj.xml" android:label="Tests for My App" />
</manifest>

上面的文件,如入了uses-library,和测试环境instrumentation。
这是必须要做的步骤,不然无法进行单元测试。

2.  定义类继承AndroidTestCase

定义一个PersonServiceTest类,继承AndroidTestCase,用于对上面的方法进行测试。
package org.wwj.test;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.wwj.domain.Person;
import org.wwj.service.PersonService;

import android.test.AndroidTestCase;
import android.util.Log;

/**
 * 单元测试类
 * @author wwj
 * 继承AndroidTestCase
 */
public class PersonServiceTest extends AndroidTestCase{
	private final static String TAG = "PersonServiceTest";		//定义打印标签
	
	/**
	 * 测试xml文件解析
	 * 在logcat中查看结果
	 * @throws Exception
	 */
	public void testPersons() throws Exception {
		//获得输入流
		InputStream xml = this.getClass().getClassLoader().getResourceAsStream("person.xml");
		List<Person> persons = PersonService.getPersons(xml);	//解析文件,返回一个集合
		for(Person person : persons) {	//增强型for循环,打印输出信息
			Log.i(TAG, person.toString());
		}
	}
	
	
	/**
	 * 测试输出文件
	 * @throws Exception
	 */
	public void testSave() throws Exception {
		List<Person> persons = new ArrayList<Person>();
		persons.add(new Person(1, "xiaoming", 20));
		persons.add(new Person(2, "lishi", 21));
		persons.add(new Person(3, "wangwu", 22));
		
		//定义一个文件,保存在当前上下文下的files目录下,输出文件为wwj.xml
		File xmlFile = new File(getContext().getFilesDir(), "wwj.xml");
		FileOutputStream out = new FileOutputStream(xmlFile);
		PersonService.save(persons, out);
		
	}
}

3. 找到测试的方法,右键Run--Run Android JUnit  Test
如果有如下的测试效果,说明测试通过

Android中使用Pull解析器解析xml文件+进行简单的单元测试_第1张图片
     



你可能感兴趣的:(android)