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;
	}