解析速度快,占用内存少,采用事件驱动,即不需要加载完整个文档,而是按内容顺序解析文档,在此过程中,其会判断当前读到的内容是否符合XML语法定义
AD:
Android平台上可以使用SimpleAPIforXML(SAX),DocumentObjectModel(DOM)和Android附带的pull解析器解析XML文件
众所周知,,DOM解析方式很耗内存,优先使用SAX或者pull
SAX:
解析速度快,占用内存少,采用事件驱动,即不需要加载完整个文档,而是按内容顺序解析文档,在此过程中,其会判断当前读到的内容是否符合XML语法定义,如果符合就会触发事件,所谓事件,其实就是一些callback方法,具体方法含义比较简单,看文档即可,定义在DefaultHandler接口中(SAX已内置到JDK5.0中)
待解析xml文件musics.xml:
<?xmlversion="1.0"encoding="utf-8"?>
<musics>
<musicid="1">
<name>黑色幽默</name>
<albumName>Jay</albumName>
<year>2000</year>
</music>
<musicid="2">
<name>爱在西元前</name>
<albumName>范特西</albumName>
<year>2001</year>
</music>
<musicid="3">
<name>回到过去</name>
<albumName>八度空间</albumName>
<year>2002</year>
</music>
<musicid="4">
<name>东风破</name>
<albumName>叶惠美</albumName>
<year>2003</year>
</music>
<musicid="5">
<name>七里香</name>
<albumName>七里香</albumName>
<year>2004</year>
</music>
<musicid="6">
<name>一路向北</name>
<albumName>十一月的萧邦</albumName>
<year>2005</year>
</music>
</musics>
实体类MusicEntity就不贴了,四个属性,上面的xml中也可以看出.
实现了DefaultHandler接口的SaxHandler:
publicclassSaxHandlerextendsDefaultHandler{
privatestaticfinalStringTAG="lanyan";
privateList<MusicEntity>musics;
privateMusicEntitymusic;
privateStringpreTag;
@Override
publicvoidstartDocument()throwsSAXException{
musics=newArrayList<MusicEntity>();
}
@Override
publicvoidstartElement(Stringuri,StringlocalName,StringqName,
Attributesattributes)throwsSAXException{
if("music".equals(localName)){
music=newMusicEntity();
music.setId(Integer.parseInt(attributes.getValue("id")));
}
preTag=localName;
}
@Override
publicvoidcharacters(char[]ch,intstart,intlength)
throwsSAXException{
if(null!=music){
Stringstr=newString(ch,start,length);
if("name".equals(preTag)){
music.setName(str);
}elseif("albumName".equals(preTag)){
music.setAlbumName(str);
}elseif("year".equals(preTag)){
music.setYear(Integer.parseInt(str));
}
}
}
@Override
publicvoidendElement(Stringuri,StringqName)
throwsSAXException{
if("music".equals(localName)&&null!=music){
musics.add(music);
music=null;
}
preTag=null;
}
@Override
publicvoidendDocument()throwsSAXException{
}
publicList<MusicEntity>getMusics(){
returnmusics;
}
}
对外提供SAX解析服务的接口SaxService:
publicclassSaxService{
publicstaticList<MusicEntity>readXml(InputStreamis)throwsException{
SAXParserFactorysaxFactory=SAXParserFactory.newInstance();
SAXParserparser=saxFactory.newSAXParser();
SaxHandlerhandler=newSaxHandler();
parser.parse(is,handler);
returnhandler.getMusics();
}
}
测试方法:
publicvoidtestSaxRead(){
InputStreamis=XmlPaserTest.class.getClassLoader().getResourceAsStream("musics.xml");
try{
List<MusicEntity>musics=SaxService.readXml(is);
for(MusicEntitymusic:musics){
Log.i("lanyan",music.toString());
}
}catch(Exceptione){
e.printStackTrace();
}
}
Pull:
同样是事件驱动,不同的是不需要实现什么handler接口,标签之间value的读取也不需要通过类似characters(...)的回调方法,相关API已经封转好了
对外提供PULL解析服务的接口PullService中的xml解析方法:
publicstaticList<MusicEntity>readXml(InputStreamis)throwsException{
List<MusicEntity>musics=null;
XmlPullParserparser=Xml.newPullParser();
parser.setInput(is,"UTF-8");
inteventCode=parser.getEventType();
MusicEntitymusic=null;
while(eventCode!=XmlPullParser.END_DOCUMENT){
switch(eventCode){
caseXmlPullParser.START_DOCUMENT:
musics=newArrayList<MusicEntity>();
break;
caseXmlPullParser.START_TAG:
if("music".equals(parser.getName())){
music=newMusicEntity();
music.setId(newInteger(parser.getAttributeValue(0)));
}elseif(music!=null){
if("name".equals(parser.getName())){
music.setName(parser.nextText());
}elseif("albumName".equals(parser.getName())){
music.setAlbumName(parser.nextText());
}elseif("year".equals(parser.getName())){
music.setYear(Integer.parseInt(parser.nextText()));
}
}
break;
caseXmlPullParser.END_TAG:
if("music".equals(parser.getName())&&music!=null){
musics.add(music);
music=null;
}
break;
}
eventCode=parser.next();
}
returnmusics;
}
使用PULL解析方式生成xml文件:
PullService中的xml生成方法:
/**
*Pull生成xml数据
*@parampersons
*@paramwriter
*@throwsException
*/
publicstaticvoidwriteXml(List<MusicEntity>musics,Writerwriter)
throwsException{
XmlSerializerserializer=Xml.newSerializer();
serializer.setOutput(writer);
serializer.startDocument("UTF-8",true);
serializer.startTag(null,"musics");
for(MusicEntitymusic:musics){
serializer.startTag(null,"music");
serializer.attribute(null,"id",String.valueOf(music.getId()));
serializer.startTag(null,"name");
serializer.text(music.getName());
serializer.endTag(null,"name");
serializer.startTag(null,"albumName");
serializer.text(music.getAlbumName());
serializer.endTag(null,"albumName");
serializer.startTag(null,"year");
serializer.text(String.valueOf(music.getYear()));
serializer.endTag(null,"year");
serializer.endTag(null,"music");
}
serializer.endTag(null,"musics");
serializer.endDocument();
writer.flush();
writer.close();
}
测试方法:
publicvoidtestPullWrite()throwsException{
List<MusicEntity>musics=newArrayList<MusicEntity>();
MusicEntitymusic1=newMusicEntity();
music1.setId(1);
music1.setName("七里香");
music1.setAlbumName("七里香");
music1.setYear(2004);
musics.add(music1);
MusicEntitymusic2=newMusicEntity();
music2.setId(1);
music2.setName("一路向北");
music2.setAlbumName("十一月的萧邦");
music2.setYear(2005);
musics.add(music2);
StringWriterwriter=newStringWriter();
PullService.writeXml(musics,writer);
Log.i("lanyan",writer.toString());
}
输出结果:
<?xmlversion='1.0'encoding='UTF-8'standalone='yes'?><musics><musicid="1"><name>七里香</name><albumName>七里香</albumName><year>2004</year></music><musicid="1"><name>一路向北</name><albumName>十一月的萧邦</albumName><year>2005</year></music></musics>
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|