安卓xml序列化和pull解析笔记
好奇、学习、总结、分享
一、简介:
在安卓中SharedPreferences的作用主要是用来操作轻量级的简单数据的存取,例如把int、boolean、float、long或者String类类型的数据保存到xml文件中,或者把这些数据从xml文件中读取出来。而XmlSerializer【xml序列化】则是把大量的数据保存到xml文件中,或者从xml文件中读取这些大量的数据。
XmlSerializer序列化一般用于短信备份等场合。XmlSerializer是通过流的形式把数据写入xml文件中的。
二、使用XmlSerializer序列化器把数据保存到xml文件示例
//1、创建短信javabean对象
public class Sms {
public String id ;//序号
public String num;//电话号码
public String date;//日期
public String msg;//短信内容
}
//2模拟短信集合,把短信内容打包成一个对象放到集合中
public class SmsDao {
public static ArrayList<Sms> getAllSms(){
ArrayList<Sms> lists_sms = new ArrayList<Sms>();
Sms sms = new Sms();
sms.id = "1";
sms.num = "11110";
sms.date = "2014-06-07";
sms.msg ="过来喝杯茶";
lists_sms.add(sms);
Sms sms2 = new Sms();
sms2.id = "2";
sms2.num = "122220";
sms2.date = "2014-06-07";
sms2.msg ="你好吗?";
lists_sms.add(sms2);
Sms sms3 = new Sms();
sms3.id = "3";
sms3.num = "1000086";
sms3.date = "2014-06-07";
sms3.msg ="大爷,您该交话费了";
lists_sms.add(sms3);
return lists_sms;
}
}
XmlSerializer序列化步骤:
1.通过Xml类创建一个xml序列化对象
2.为xml序列化对象设置初始化的参数:流、编码
3.使用xml序列化对象序列化xml的文档声明信息
4.使用xml序列化对象序列化xml的根节点
5.通过循环遍历数据集合,将smss的数据以标签的形式写入序列化对象
6.设置xml序列化对象的根节点结束标签
7.结束xml文档的写入
//3 用XmlSerializer序列化把集合中的数据写入xml文件中
public static boolean backupSmsForAndroid(Context context,ArrayList<Sms> sms_lists){
try{
//1、通过Xml类创建一个xml序列化对象
XmlSerializer xs = Xml.newSerializer();
//2、为xml序列化对象设置流对象
FileOutputStream fileOutput = context.openFileOutput("SMSbackup.xml", Context.MODE_PRIVATE);
//参数1:写入xml的流对象,参数2:流的编码
xs.setOutput(fileOutput, "utf-8");
//3、写一个xml的声明头信息
//参数1:encoding:xml文件的编码,参数2: standalone:是否独立,是否有依赖的xml,true表示不依赖其他xml
xs.startDocument("utf-8", true);
//4、写一个根标签【根标签可以不要命名空间】
//参数1:namespace命名空间,可以为空,参数2:name:根标签的名称
xs.startTag(null, "Smss");
/**
xml短信格式
<Smss>
<Sms id = "1">
<num>11110</num>
<date>2014-06-07</date>
<msg>过来喝杯茶</msg>
</Sms>
*/
//5、遍历短信集合,把对象中每一条数据都写入到xml文件中
for(int i = 0 ;i < sms_lists.size();i ++){
sms = sms_lists.get(i);//获取集合中的短信对象
xs.startTag(null, "Sms");//写起始标签
//参数1:命名空间,参数2:属性名称,参数3:属性值
xs.attribute(null, "id", sms.id);//起始标签的属性值
xs.startTag(null, "num");//电话号码起始标签
xs.text(sms.num);//电话内容
xs.endTag(null, "num");//电话号码结束标签
xs.startTag(null, "date");//日期起始标签
xs.text(sms.date);//日期内容
xs.endTag(null, "date");//日期结束标签
xs.startTag(null, "msg");//短信内容起始标签
xs.text(sms.msg);//短信内容
xs.endTag(null, "msg");//短信内容结束标签
xs.endTag(null, "Sms");//Sms根节点
}
//6.设置xml序列化对象的根节点结束标签
xs.endTag(null, "Smss");//Smss根节点
//7.结束xml文档的写入
xs.endDocument();
return true;
}catch (Exception e) {
e.printStackTrace();
}
return false;
}
三、使用xmlpullparser解析器从xml文件中读取数据示例
XML的3种常用解析方式:
1、dom:
DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应节点对象(Node的子类对象),以便于调用其特有的方法。
Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容。
缺点: 一次性的完全加载整个xml文件,需要消耗大量的内存。当xml文件很大时,可能会造成内存溢出的现象。
2、sax
SAX是基于事件驱动逐行解析的,简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。
3、pull【安卓中常用】
Pull解析和sax解析一样,都是基于事件驱动逐行解析的。PULL解析器小巧轻便,解析速度快,简单易用,Android官方推荐开发者们使用Pull解析技术。Pull解析技术是第三方开发的开源技术,它同样可以应用于JavaSE开发。
Pull方式解析xml示例:
步骤
1.通过Xml类获取一个xmlpullparser对象
2.设置xmlpullparser对象的文件读取流和编码
3.获取解析器当前的事件类型
4.循环遍历事件类型是否是文档结束
5.在循环中判断事件类型做相应的解析操作.
//pull方式解析xml文件
public static int restoreSms(Context context){
try{
//1、通过Xml类获取一个Xmlpullparser的对象
XmlPullParser xpp = Xml.newPullParser();
ArrayList<Sms> sms_lists = null;
Sms sms = null;
//2、为解析器对象设置一个文件读取流【把xml文件以流的形式读取】
FileInputStream fileInput = context.openFileInput("smsbackup2.xml");
//参数1:解析的xml文件的流对象,参数2:流的编码
xpp.setInput(fileInput, "utf-8");
//3、获取解析器的当前事件类型
int type = xpp.getEventType();
//4、通过循环判断解析器的类型,做数据的解析
while(type != XmlPullParser.END_DOCUMENT){
//5、判断事件的类型是开始标签,还是结束标签
switch (type) {
case XmlPullParser.START_TAG://开始标签
//判断当前开始标签的名称
if("Smss".equals(xpp.getName())){
//初始化一个集合用来存放短信内容
sms_lists = new ArrayList<Sms>();
}else if("Sms".equals(xpp.getName())){
//初始化一个短信对象
sms = new Sms();
//获取当前标签上的一个属性
String id = xpp.getAttributeValue(0);
sms.id = id;
}else if("num".equals(xpp.getName())){
//获取当前标签的下一个文本内容
String num = xpp.nextText();
sms.num = num;
}else if("date".equals(xpp.getName())){
String date = xpp.nextText();
sms.date = date;
}else if("msg".equals(xpp.getName())){
String msg = xpp.nextText();
sms.msg = msg;
}
break;
case XmlPullParser.END_TAG://结束标签
if("Sms".equals(xpp.getName())){
//如果当前标签是Sms的结束标签时,需要将一个短信对象添加到集合中
sms_lists.add(sms);
}
break;
}
//6、获取下一个事件类型
type = xpp.next();
}
//遍历解析到的xml数据
for (Sms sms2 : sms_lists) {
System.out.println(sms2.id +" : "+sms2.num +" : "+sms2.date + ": "+sms2.msg);
}
return sms_lists.size();
}catch (Exception e) {
e.printStackTrace();
}
return 0;
}
最后在main_ctivity中调用即可,布局代码和main_ctivity代码省略
四、xStream框架
在实际工程中,常用xStream框架。xStream可以轻易的将Java对象和xml文档相互转换,而且可以修改某个特定的属性和节点名称,而且也支持json的转换。
想要深入学习xStream框架的同学可以参考下面2篇优秀的文章:
xStream完美转换XML、JSON:http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197.html
android 中XML和对象转换利器Xstream的使用:http://www.2cto.com/kf/201207/140549.html
当然还有网络上还有很多类似的优秀文章没有一一列举,大家可以根据自己的需求收索相关xStream框架的资料。
五、补充知识:context上下文的强大功能,它可以获取所有的资源。如下,
//通过上下文获取应用程序的一个资源对象
Resources resources = context.getResources();
//通过资源对象可以获取一个Assets对象的管理对象,并且可以获assets文件的流
InputStream fileInput = resources.getAssets().open("smsBackup2.xml");//获取assets目录下smsBackup2.xml文件