Android提供了一个序列化方法Xml.newSerializer()用于生成xml文件,首先,我们需要对序列化器进行初始化,指定xml数据写入的文件路径及文件的编码方式。然后利用序列化器提供的方法写xml文件内容。主要方法有:
startDocument(encoding, standalone):写文件开始标签,encoding表示文件编码,standalone表示文件是否独立。
startTag(namespace, name):写标签头,namespace表示命名空间,name表示文件标签名称
attribute(namespace, name, value):设置标签属性,namespace表示命名空间,value表示标签属性值
text(text):设置标签包含的内容,text表示内容文本
endTag(namespace, name):写标签结束符,namespace表示命名空间,name表示对应的结束标签名称
endDocument():文件编写结束
其中startTag(namespace, name)方法和endTag(namespace, name)方法、startDocument(encoding, standalone)和endDocument()是成对出现的。
采用Xml.newSerializer()方法生成xml文件较采用StringBuilder()方法生成xml文件更方便,它能方便的添加标签属性值,代码也更简洁;当输入的内容有特殊符号(如“<"、">”等)会自动将其进行转义,而不影响xml文档的生成。
下面给出一段简单生成短信信息的xml文件的关键代码
public void backSms2(Context context,List<SmsInfoBean> smsInfoBeans) throws Exception{
XmlSerializer xmlSerializer=Xml.newSerializer();
File file=new File(context.getFilesDir(),"backsms2.xml");
FileOutputStream fos=new FileOutputStream(file);
//初始化序列化器,指定xml数据写入到哪个文件,并且指定文件的编码方式
xmlSerializer.setOutput(fos, "utf-8");
xmlSerializer.startDocument("utf-8", true);//xml文件是否独立,指定为true
xmlSerializer.startTag(null, "smss");
for(SmsInfoBean smsInfoBean:smsInfoBeans){
xmlSerializer.startTag(null, "sms");
xmlSerializer.attribute(null, "id", smsInfoBean.getId()+"");
xmlSerializer.startTag(null, "body");
xmlSerializer.text(smsInfoBean.getBody());
xmlSerializer.endTag(null, "body");
xmlSerializer.startTag(null, "address");
xmlSerializer.text(smsInfoBean.getAddress());
xmlSerializer.endTag(null, "address");
xmlSerializer.startTag(null, "type");
xmlSerializer.text(smsInfoBean.getType()+"");
xmlSerializer.endTag(null, "type");
xmlSerializer.startTag(null, "date");
xmlSerializer.text(smsInfoBean.getDate()+"");
xmlSerializer.endTag(null, "date");
xmlSerializer.endTag(null, "sms");
}
xmlSerializer.endTag(null, "smss");
xmlSerializer.endDocument();
fos.close();
Toast.makeText(context, "备份成功", 0).show();
}
完成xml编写后,我们还可以对已写好的xml进行导入。
xml文件解析方式:
DOM解析:将xml文件一次性加载到内存中,生成一个树状结构。但消耗的内存比较大,xml文件较大时不推荐使用该解析。
SAX解析:基于事件的方式进行解析,事件是自上而下的。解析速度快,效率高,但不能倒退。
Pull解析:android下提供的新的解析方式,类似于SAX解析,也是基于事件的方式进行解析。代码便于阅读和理解。
Pull解析xml的逻辑与系列化器生成xml的逻辑类似,pull解析利用getEventType()方法获取当前事件类型后,对xml文件进行逐条遍历解析。
下面给出一段简单解析短信信息xml文件的关键代码
public List<SmsInfoBean> getSmsInfos(Context context) throws Exception{
XmlPullParser xmlPullParser= Xml.newPullParser();
File file=new File(context.getFilesDir(),"backsms2.xml");
FileInputStream is=new FileInputStream(file);
xmlPullParser.setInput(is,"utf-8");
List<SmsInfoBean> smsInfoBeans=null;
SmsInfoBean smsInfoBean=null;
int type=xmlPullParser.getEventType();//获取当前事件类型
while (type!=XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if(xmlPullParser.getName().equals("smss")){
//解析到全局开始标签
smsInfoBeans=new ArrayList<SmsInfoBean>();
}else if(xmlPullParser.getName().equals("sms")){
smsInfoBean=new SmsInfoBean();
smsInfoBean.setId(Integer.parseInt(xmlPullParser.getAttributeValue(0)));
}else if(xmlPullParser.getName().equals("body")){
smsInfoBean.setBody(xmlPullParser.nextText());
}else if(xmlPullParser.getName().equals("address")){
smsInfoBean.setAddress(xmlPullParser.nextText());
}else if(xmlPullParser.getName().equals("type")){
smsInfoBean.setType(Integer.parseInt(xmlPullParser.nextText()));
}else if(xmlPullParser.getName().equals("date")){
smsInfoBean.setDate(Long.parseLong((xmlPullParser.nextText())));
}
break;
case XmlPullParser.END_TAG:
if(xmlPullParser.getName().equals("sms")){
//一条短信信息已经处理完毕
smsInfoBeans.add(smsInfoBean);
smsInfoBean=null;
}
break;
}
type=xmlPullParser.next();
}
is.close();
return smsInfoBeans;
}