Android中XML文件的序列化和解析
一、XML文件的序列化
说白了,序列化就是就是将数据存储起来,又叫持久化。XML的序列化就是将对象类型的数据将他们保存在XML文件中。下面我们来说说XML序列化的过程。
第一步:准备数据源
这里我们就以List集合为例,假设集合中有20个学生对象,我们需要将这些对象保存到student.xml文件中,那么我们就需要一个Student类和一个List集合,将学生对象添加到集合中。
public class Student {
private String name;
private String age;
...
//此处省略get/set方法和构造函数
}
再将学生对象添加到集合当中
private List<Student> students;
students =new ArrayList<Student>();
for(int i=0;i<10;i++){
Student stu=new Student("张三"+i,10+i+"");
students.add(stu);
}
第二步:开始序列化
- 获取序列化器
XmlSerializer serializer = Xml.newSerializer();
- 指定存储xml文件的位置和文件权限。我们一般将文件保存在内存中。
//获取输入流
FileOutputStream fos =openFileOutput("student.xml",MODE_PRIVATE);
//设置输入流和编码
serializer.setOutput(fos,"utf-8");
- 接下来就是开始写入文档了。XmlSerializer提供了一下方法:
- void startDocument (String encoding, Boolean standalone)
- XmlSerializer startTag (String namespace, String name)
- XmlSerializer text (String text)
- XmlSerializer endTag (String namespace, String name)
- void endDocument ()
由于写入的对象较多,我们采用for循环将学生对象写入文档。
// 开始文档
serializer.startDocument("utf-8", true);
serializer.startTag(null, "students");
// 循环写入对象
for (int i = 0; i < students.size(); i++) {
serializer.startTag(null, "student");
// 写入名字
serializer.startTag(null, "name");
serializer.text(students.get(i).getName());
serializer.endTag(null, "name");
// 写入年龄
serializer.startTag(null, "age");
serializer.text(students.get(i).getAge());
serializer.endTag(null, "age");
serializer.endTag(null, "student");
}
serializer.endTag(null, "students");
// 结束文档
serializer.endDocument();
这时,将对象序列化为xml文件完成。我们可以在手机的data/data/项目名/files/下面找到我们写入的student.xml文件。
二、XML文件的解析
xml文件的解析和序列化恰好相反,我们需要将XML文件解析成为一个一个的对象。
第一步:获取解析器
XmlPullParser parser = Xml.newPullParser();
第一步:获取输出流
FileInputStream fis = openFileInput("student.xml");
parser.setInput(fis, "utf-8");
前面这两步和序列化是相反的。
接下来我们就开始解析xml文件,想来看代码:
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
//读取到根标签,创建数组
if (parser.getName().equals
("students")) {
list = new ArrayList<Student>();
//读取到student说明要开始创建对象
} else if (parser.getName().equals("student")) {
stu = new Student();
//读取到属性就要设置对象的属性
} else if (parser.getName().equals("name")) {
//获取文本信息
String name = parser.nextText();
stu.setName(name);
} else if (parser.getName().equals("age")) {
String age = parser.nextText();
stu.setAge(age);
} else if (parser.getName().equals("sex")) {
String sex = parser.nextText();
stu.setSex(sex);
}
break;
case XmlPullParser.END_TAG:
//读到student,说明一个对象对去完毕添加到list集合中,重置stu
if (parser.getName().equals("student")) {
list.add(stu);
stu = null;
}
break;
}
//一轮结束后要将解析器推进
eventType = parser.next();
}
//System.out.println(list);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
注意点:
1.eventType表示当前的事件类型,它对应着时间START_TAG, END_TAG, TEXT、START_DOCUMENT、END_DOCUMENT的常量值
2.当我们在while语句中判断条件时,是用eventType与XmlPullarser.事件比较,而不是用解析器来比较,这一点时间长了很容易搞忘记
3.在下面判断读到那个便签时,是获取解析器的名字,然后与标签名比较。例如parser.getName().equals(“student”);
4.在进行解析的过程中,循环运行一遍之后,我们千万不要忘记了要将事件推进。这里是最容易忘记的。当我们写完代码运行执行,发现只打印了一个对象,那么肯定是没有将事件推进。总结一下:eventType用来判断事件类型,所以它要放在switch语句中。这些事件被定义为XmlPullParser类的整型常量,获取的时候为XmlPullParser.END_TAG这个样式。事件进行过程中,通过parser.getName()判断解析到那个事件。最后,记得将事件推进。