Android使用pull解析器解析xml文件
2016-05-22 00:00
609 查看
转载出处:http://blog.csdn.net/lyh7736362/article/details/6230847
以下面这个xml文件为例
[xhtml]
view plain
copy
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="23">
<name>李明</name>
<age>30</age>
</person>
<person id="20">
<name>李向梅</name>
<age>25</age>
</person>
</persons>
里面的所有东西都可以统称为节点<person> 李明 30 都为节点
而更准确的说 <person> <name> <age>为element,即为元素
而 李明 30 为text,即为文本节点
而 id 为属性,"23"为属性值
第2行与第3行之间的空格也是一个节点
新建一个person类在lyh.domain 根据xml文件设置相对应的变量和方法
[java]
view plain
copy
package lyh.domain;
public class Person {
private int id;
private String name;
private short age;
public Person() {
}
public Person(int id, String name, short age) {
this.id = id;
this.name = name;
this.age = age;
}
public Person(String name, short age) {
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 short getAge() {
return age;
}
public void setAge(short age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "id="+id+",name="+ name + ",age="+ age;
}
}
编写业务bean
[java]
view plain
copy
package lyh.service;
import java.io.InputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import lyh.domain.Person;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
public class PullPersonService {
public static void writeXml(List<Person> persons , Writer writer) throws Exception{
//1.使用android的XML工具类去创建一个序列化对象
XmlSerializer serializer = Xml.newSerializer();
//2.设置xml文件输出的位置
serializer.setOutput(writer);
//3.设置xml字符编码和standalone属性
serializer.startDocument("UTF-8", true);
//4.设置开始标签的命名空间前缀和标签的名称,startTag与endTag应成对出现
serializer.startTag(null, "persons");
//5.通过迭代从list中取出每个person以便写出
for(Person person : persons){
serializer.startTag(null, "person");
//6.设置id的值
serializer.attribute(null, "id", String.valueOf(person.getId()));
//7.设置name的文本
serializer.startTag(null, "name");
serializer.text(person.getName());
serializer.endTag(null, "name");
//8.设置age的文本
serializer.startTag(null, "age");
serializer.text(String.valueOf(person.getAge()));
serializer.endTag(null, "age");
serializer.endTag(null, "person");
}
//9.设置结束标签的命名空间前缀和标签的名称
serializer.endTag(null, "persons");
//10.设置结束文档
serializer.endDocument();
//11.writer为缓冲输出类,需要刷出到文件,然后关闭
writer.flush();
writer.close();
}
public static List<Person> readXml(InputStream inStream) throws Exception{
List<Person> persons = null;
Person person = null;
//1.使用android提供的Xml类new一个XmlPullerParser,即new一个XmlPull解析器
XmlPullParser parser = Xml.newPullParser();
//2.然后设置需要解析的xml文件,第一个参数为输入流,第二个参数为字符编码
parser.setInput(inStream, "UTF-8");
//3.触发事件,当这个方法遇到某个字符符合XML语法,就会触发这个语法所代表的数字
int eventCode = parser.getEventType();
//4.XML文件的第一行为开始文档事件START_DOCUMENT,最后一行为结束文档事件END_DOCUMENT,我们需要不断读取xml文件的内容
while( XmlPullParser.END_DOCUMENT != eventCode ){
//5.我们对这个事件进行处理,我们感兴趣的是<person>这个元素
switch(eventCode){
case XmlPullParser.START_DOCUMENT://开始文档事件
persons = new ArrayList<Person>();//初始化用来存放person的List
break;
case XmlPullParser.START_TAG://6.如果这个事件是开始元素(例如<persons>)事件
if("person".equals(parser.getName())){
person = new Person();
//7.使用解析器得到当前元素的属性,即id
person.setId(new Integer(parser.getAttributeValue(0)));
}else if(person!=null){
if("name".equals(parser.getName())){
//8.如果当前元素为开始标签,下一个元素为文本,就会返回这个文本
person.setName(parser.nextText());
}else if("age".equals(parser.getName())){
//8.如果当前元素为开始标签,下一个元素为文本,就会返回这个文本
person.setAge(new Short(parser.nextText()));
}
}
break;
case XmlPullParser.END_TAG://9.如果这个事件是结束元素(例如</persons>)事件
if("person".equals(parser.getName()) && person != null){
//往List里添加person,并把person置空,以便下次的读取
persons.add(person);
person = null;
}
break;
}
//10.当我们第一次调用getEventType()方法,得到的是XML文件的第一行,即<?xml version="1.0" encoding="UTF-8"?>,所以需要再往下一行读取
//接着就遇到了<persons>,触发一个事件,再往下就是空格,触发一个事件,如此类推
eventCode = parser.next();
}
//11.返回储存好的list
return persons;
}
}
编写单元测试类,需要测试时,请把itcase.xml放入到src文件夹中
[java]
view plain
copy
package lyh.xml;
import java.io.InputStream;
import java.util.List;
import lyh.domain.Person;
import lyh.service.PullPersonService;
import android.test.AndroidTestCase;
import android.util.Log;
public class XmlPersonServiceTest extends AndroidTestCase{
private static final String TAG = "PullPersonServiceTest";
//使用pull解析xml内容
public void testPullReadXml() throws Exception{
InputStream inStream = XmlPersonServiceTest.class.getClassLoader().getResourceAsStream("itcase.xml");
List<Person> persons = PullPersonService.readXml(inStream);
for(Person person : persons){
Log.i(TAG, person.toString());
}
inStream.close();
}
}
配置AndroidManifest.xml文件,为其配置单元测试环境
在<application android:icon="@drawable/icon" android:label="@string/app_name">
下面加入
<uses-library android:name="android.test.runner"/>
在 <uses-sdk android:minSdkVersion="10" />下面加入
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="lyh.xml" android:label="Tests for My App"/>
注意android:targetPackage="lyh.xml" 要与原配置文件中的package的一致
在通过了单元测试以后就可以在XmlActivity中编写了
将TextView的id设置为result,将xml文件内容输出到手机屏幕上
[java]
view plain
copy
package lyh.xml;
import java.io.InputStream;
import java.util.List;
import lyh.domain.Person;
import lyh.service.PullPersonService;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class XmlActivity extends Activity {
private static final String TAG = "XmlActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView resultView = (TextView)this.findViewById(R.id.result);
InputStream inStream = XmlActivity.class.getClassLoader().getResourceAsStream("itcase.xml");
try {
List<Person> persons = PullPersonService.readXml(inStream);
StringBuilder sb = new StringBuilder();
for( Person person : persons){
sb.append(person.toString()).append("/n");
}
resultView.setText(sb.toString());
} catch (Exception e) {
Log.e(TAG, e.toString());
Toast.makeText(this, "解析失败", Toast.LENGTH_LONG).show();
}
}
}
使用pull输出xml文件
在PullPersonService编写一个writeXml方法
[java]
view plain
copy
public static void writeXml(List<Person> persons , Writer writer) throws Exception{
//1.使用android的XML工具类去创建一个序列化对象
XmlSerializer serializer = Xml.newSerializer();
//2.设置xml文件输出的位置
serializer.setOutput(writer);
//3.设置xml字符编码和standalone属性
serializer.startDocument("UTF-8", true);
//4.设置开始标签的命名空间前缀和标签的名称,startTag与endTag应成对出现
serializer.startTag(null, "persons");
//5.通过迭代从list中取出每个person以便写出
for(Person person : persons){
serializer.startTag(null, "person");
//6.设置id的值
serializer.attribute(null, "id", String.valueOf(person.getId()));
//7.设置name的文本
serializer.startTag(null, "name");
serializer.text(person.getName());
serializer.endTag(null, "name");
//8.设置age的文本
serializer.startTag(null, "age");
serializer.text(String.valueOf(person.getAge()));
serializer.endTag(null, "age");
serializer.endTag(null, "person");
}
//9.设置结束标签的命名空间前缀和标签的名称
serializer.endTag(null, "persons");
//10.设置结束文档
serializer.endDocument();
//11.writer为缓冲输出类,需要刷出到文件,然后关闭
writer.flush();
writer.close();
}
在XmlPersonServiceTest中写一个单元测试,当然也可以在activity中写,不过最好先进行单元测试
[java]
view plain
copy
//使用pull写入xml内容
public void testPullWriteXml() throws Exception{
//1.设置输出流,输出到persons.xml且这个文件的权限为可读的
FileOutputStream outStream = this.getContext().openFileOutput("persons.xml",Context.MODE_WORLD_READABLE);
OutputStreamWriter writer = new OutputStreamWriter(outStream,"UTF-8");
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(11,"老毛",(short)20));
persons.add(new Person(12,"撒旦",(short)30));
persons.add(new Person(13,"飞飞",(short)31));
PullPersonService.writeXml(persons,writer);
outStream.flush();
outStream.close();
}
进行单元测试以后就可以使用文件浏览器到data.lyh.xml.files文件夹下查看到persons.xml文件了,可以使用右上方的 Pull a file from the device按钮把文件提取到电脑上查看
以下面这个xml文件为例
[xhtml]
view plain
copy
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="23">
<name>李明</name>
<age>30</age>
</person>
<person id="20">
<name>李向梅</name>
<age>25</age>
</person>
</persons>
里面的所有东西都可以统称为节点<person> 李明 30 都为节点
而更准确的说 <person> <name> <age>为element,即为元素
而 李明 30 为text,即为文本节点
而 id 为属性,"23"为属性值
第2行与第3行之间的空格也是一个节点
新建一个person类在lyh.domain 根据xml文件设置相对应的变量和方法
[java]
view plain
copy
package lyh.domain;
public class Person {
private int id;
private String name;
private short age;
public Person() {
}
public Person(int id, String name, short age) {
this.id = id;
this.name = name;
this.age = age;
}
public Person(String name, short age) {
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 short getAge() {
return age;
}
public void setAge(short age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "id="+id+",name="+ name + ",age="+ age;
}
}
编写业务bean
[java]
view plain
copy
package lyh.service;
import java.io.InputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import lyh.domain.Person;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.util.Xml;
public class PullPersonService {
public static void writeXml(List<Person> persons , Writer writer) throws Exception{
//1.使用android的XML工具类去创建一个序列化对象
XmlSerializer serializer = Xml.newSerializer();
//2.设置xml文件输出的位置
serializer.setOutput(writer);
//3.设置xml字符编码和standalone属性
serializer.startDocument("UTF-8", true);
//4.设置开始标签的命名空间前缀和标签的名称,startTag与endTag应成对出现
serializer.startTag(null, "persons");
//5.通过迭代从list中取出每个person以便写出
for(Person person : persons){
serializer.startTag(null, "person");
//6.设置id的值
serializer.attribute(null, "id", String.valueOf(person.getId()));
//7.设置name的文本
serializer.startTag(null, "name");
serializer.text(person.getName());
serializer.endTag(null, "name");
//8.设置age的文本
serializer.startTag(null, "age");
serializer.text(String.valueOf(person.getAge()));
serializer.endTag(null, "age");
serializer.endTag(null, "person");
}
//9.设置结束标签的命名空间前缀和标签的名称
serializer.endTag(null, "persons");
//10.设置结束文档
serializer.endDocument();
//11.writer为缓冲输出类,需要刷出到文件,然后关闭
writer.flush();
writer.close();
}
public static List<Person> readXml(InputStream inStream) throws Exception{
List<Person> persons = null;
Person person = null;
//1.使用android提供的Xml类new一个XmlPullerParser,即new一个XmlPull解析器
XmlPullParser parser = Xml.newPullParser();
//2.然后设置需要解析的xml文件,第一个参数为输入流,第二个参数为字符编码
parser.setInput(inStream, "UTF-8");
//3.触发事件,当这个方法遇到某个字符符合XML语法,就会触发这个语法所代表的数字
int eventCode = parser.getEventType();
//4.XML文件的第一行为开始文档事件START_DOCUMENT,最后一行为结束文档事件END_DOCUMENT,我们需要不断读取xml文件的内容
while( XmlPullParser.END_DOCUMENT != eventCode ){
//5.我们对这个事件进行处理,我们感兴趣的是<person>这个元素
switch(eventCode){
case XmlPullParser.START_DOCUMENT://开始文档事件
persons = new ArrayList<Person>();//初始化用来存放person的List
break;
case XmlPullParser.START_TAG://6.如果这个事件是开始元素(例如<persons>)事件
if("person".equals(parser.getName())){
person = new Person();
//7.使用解析器得到当前元素的属性,即id
person.setId(new Integer(parser.getAttributeValue(0)));
}else if(person!=null){
if("name".equals(parser.getName())){
//8.如果当前元素为开始标签,下一个元素为文本,就会返回这个文本
person.setName(parser.nextText());
}else if("age".equals(parser.getName())){
//8.如果当前元素为开始标签,下一个元素为文本,就会返回这个文本
person.setAge(new Short(parser.nextText()));
}
}
break;
case XmlPullParser.END_TAG://9.如果这个事件是结束元素(例如</persons>)事件
if("person".equals(parser.getName()) && person != null){
//往List里添加person,并把person置空,以便下次的读取
persons.add(person);
person = null;
}
break;
}
//10.当我们第一次调用getEventType()方法,得到的是XML文件的第一行,即<?xml version="1.0" encoding="UTF-8"?>,所以需要再往下一行读取
//接着就遇到了<persons>,触发一个事件,再往下就是空格,触发一个事件,如此类推
eventCode = parser.next();
}
//11.返回储存好的list
return persons;
}
}
编写单元测试类,需要测试时,请把itcase.xml放入到src文件夹中
[java]
view plain
copy
package lyh.xml;
import java.io.InputStream;
import java.util.List;
import lyh.domain.Person;
import lyh.service.PullPersonService;
import android.test.AndroidTestCase;
import android.util.Log;
public class XmlPersonServiceTest extends AndroidTestCase{
private static final String TAG = "PullPersonServiceTest";
//使用pull解析xml内容
public void testPullReadXml() throws Exception{
InputStream inStream = XmlPersonServiceTest.class.getClassLoader().getResourceAsStream("itcase.xml");
List<Person> persons = PullPersonService.readXml(inStream);
for(Person person : persons){
Log.i(TAG, person.toString());
}
inStream.close();
}
}
配置AndroidManifest.xml文件,为其配置单元测试环境
在<application android:icon="@drawable/icon" android:label="@string/app_name">
下面加入
<uses-library android:name="android.test.runner"/>
在 <uses-sdk android:minSdkVersion="10" />下面加入
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="lyh.xml" android:label="Tests for My App"/>
注意android:targetPackage="lyh.xml" 要与原配置文件中的package的一致
在通过了单元测试以后就可以在XmlActivity中编写了
将TextView的id设置为result,将xml文件内容输出到手机屏幕上
[java]
view plain
copy
package lyh.xml;
import java.io.InputStream;
import java.util.List;
import lyh.domain.Person;
import lyh.service.PullPersonService;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
public class XmlActivity extends Activity {
private static final String TAG = "XmlActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView resultView = (TextView)this.findViewById(R.id.result);
InputStream inStream = XmlActivity.class.getClassLoader().getResourceAsStream("itcase.xml");
try {
List<Person> persons = PullPersonService.readXml(inStream);
StringBuilder sb = new StringBuilder();
for( Person person : persons){
sb.append(person.toString()).append("/n");
}
resultView.setText(sb.toString());
} catch (Exception e) {
Log.e(TAG, e.toString());
Toast.makeText(this, "解析失败", Toast.LENGTH_LONG).show();
}
}
}
使用pull输出xml文件
在PullPersonService编写一个writeXml方法
[java]
view plain
copy
public static void writeXml(List<Person> persons , Writer writer) throws Exception{
//1.使用android的XML工具类去创建一个序列化对象
XmlSerializer serializer = Xml.newSerializer();
//2.设置xml文件输出的位置
serializer.setOutput(writer);
//3.设置xml字符编码和standalone属性
serializer.startDocument("UTF-8", true);
//4.设置开始标签的命名空间前缀和标签的名称,startTag与endTag应成对出现
serializer.startTag(null, "persons");
//5.通过迭代从list中取出每个person以便写出
for(Person person : persons){
serializer.startTag(null, "person");
//6.设置id的值
serializer.attribute(null, "id", String.valueOf(person.getId()));
//7.设置name的文本
serializer.startTag(null, "name");
serializer.text(person.getName());
serializer.endTag(null, "name");
//8.设置age的文本
serializer.startTag(null, "age");
serializer.text(String.valueOf(person.getAge()));
serializer.endTag(null, "age");
serializer.endTag(null, "person");
}
//9.设置结束标签的命名空间前缀和标签的名称
serializer.endTag(null, "persons");
//10.设置结束文档
serializer.endDocument();
//11.writer为缓冲输出类,需要刷出到文件,然后关闭
writer.flush();
writer.close();
}
在XmlPersonServiceTest中写一个单元测试,当然也可以在activity中写,不过最好先进行单元测试
[java]
view plain
copy
//使用pull写入xml内容
public void testPullWriteXml() throws Exception{
//1.设置输出流,输出到persons.xml且这个文件的权限为可读的
FileOutputStream outStream = this.getContext().openFileOutput("persons.xml",Context.MODE_WORLD_READABLE);
OutputStreamWriter writer = new OutputStreamWriter(outStream,"UTF-8");
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(11,"老毛",(short)20));
persons.add(new Person(12,"撒旦",(short)30));
persons.add(new Person(13,"飞飞",(short)31));
PullPersonService.writeXml(persons,writer);
outStream.flush();
outStream.close();
}
进行单元测试以后就可以使用文件浏览器到data.lyh.xml.files文件夹下查看到persons.xml文件了,可以使用右上方的 Pull a file from the device按钮把文件提取到电脑上查看
相关文章推荐
- Android计算器功能的实现
- ubuntu环境开发android时候无法找到aapt
- 【自用】canvas.drawText()中y坐标的位置问题,Android(java)的一个坑。。附Kotlin。。
- Android 之动态加载代码
- Android Studio使用Lambda
- Android进阶学习-Canvas使用7行代码自定义圆形头像
- Android进阶学习-实现卡券效果
- Android进阶学习--十几行代码实现美女撕衣服效果
- Android进阶学习-着色器/渲染器
- Android进阶学习-实现图片倒影的效果
- Android中如何为Fragment中的按钮添加监听事件
- Learning Handler
- Android day4:Java的类型转换、Scanner、错误类型
- Android RxJava使用场景小结
- android搜索框功能实现
- Android——View事件分发机制
- android开发框架
- Aandroid 多线程断点续传同时下载多个大文件
- 一、安卓系统源码下载
- android wifi不能连接中文AP