Android平台下sax,dom,pull解析

本文介绍了Android中三种XML解析方式:Dom、Sax和Pull,并详细对比了它们的特点及适用场景。通过对同一XML文件进行解析实验,得出Pull解析方式在时间和资源消耗上更优。

1.Android中三种XML的解析方式,分别为Dom,Sax,Pull,其中Pull的解析方式最优

2.Dom,Sax,Pull解析方式的区别

(1).Dom解析方式:

首先一下子加载整个文档然后再挨个节点解析,费流量

优点:对于处理大文档,以及能力强的CPU性能比较快

缺点:对于处理能力不够强的CPU一下子可能受不了,就像一个人一口先吃下一个大西瓜,再来嚼.

(2).Sax解析方式:

SAX是事件驱动型解析方式

虽说是事件驱动型的和PULL差不多,但没有像pull那样提供next接口,想向下继续解析就向下,没有灵活性,死板,包括得到数据也是用模板弄好,对于特殊的数据组装还要用变量控制。

sax是选择性的解析,他是解析符合条件的内容。

手动停止:
解析完需要的东西后就抛异常吧,比如throw new SAXException("已拿到数据,中断解析!!!");

(3).Pull的解析方式:

Pull驱动型解析方式,加载时不把所有的节点都加载到解析机里,只是去一个一个节点去查找,如果是一个节点而且需要这个节点就取出来,不像DOM,不管你要不要都放在解析机里,要拿就拿,不拿就算了.,减少流量的使用

3.综上觉得Pull解析方式最优,通过调试代码发现,解析同一个XML文件,pull解析方式花的时间最少.

核心代码如下:

//DOM解析方式

privateList<River>fetchRiverFromXmlByDom(StringfileName){

longstartTime=System.currentTimeMillis();

List<River>rivers=newArrayList<River>();

//加载xml文档的工厂

DocumentBuilderFactoryfactory=DocumentBuilderFactory.newInstance();

InputStreaminputStream=null;

try{

DocumentBuilderbuilder=factory.newDocumentBuilder();

//加入文件流

inputStream=getAssets().open(fileName);

//转化为decument文档对象

Documentdocument=builder.parse(inputStream);

//获得最根节点

Elementroot=document.getDocumentElement();

//通过tag获得所有根节点下面的节点

NodeListnodeList=root.getElementsByTagName(riverStr);

//得到根节点下面有多少个节点

intnoteListSize=nodeList.getLength();

//声明river对象,river类中包含所有的节点string

Riverriver=null;

for(inti=0;i<noteListSize;i++){

river=newRiver();

//获得节点元素

Elementelement=(Element)nodeList.item(i);

//设置通过属性名得到的节点元素

river.setName(element.getAttribute(nameStr));

river.setLength(Integer.parseInt(element.getAttribute(lengthStr)));

//通过tag名得到所有节点,再取得第一个节点(因为只有一个节点,如果这里面还有节点得再来一个类似的循环)

ElementintroTag=(Element)element.getElementsByTagName(introductionStr).item(0);

river.setIntroduction(introTag.getFirstChild().getNodeValue());

ElementimageUrlTag=(Element)element.getElementsByTagName(imageurlStr).item(0);

river.setImageurl(imageUrlTag.getFirstChild().getNodeValue());

//收集所有的节点到这个集合里

rivers.add(river);

}

}catch(ParserConfigurationExceptione){

e.printStackTrace();

}catch(IOExceptione){

e.printStackTrace();

}catch(SAXExceptione){

e.printStackTrace();

}

Log.d(T,"execfetchRiverFromXmlByDomusetime="

+(System.currentTimeMillis()-startTime));

returnrivers;

}

SAX解析方式:

privateList<River>fetchRiverFormXmlBySAX(StringfileName){

longstartTime=System.currentTimeMillis();

List<River>rivers=null;

SAXParserFactoryfactory=SAXParserFactory.newInstance();

InputStreaminputStream=null;

try{

//得到解析机

SAXParserparser=factory.newSAXParser();

//读取数据

XMLReaderreader=parser.getXMLReader();

//取数据的句柄

MySaxHandlerhandler=newMySaxHandler();

reader.setContentHandler(handler);

inputStream=getAssets().open(fileName);

reader.parse(newInputSource(inputStream));

rivers=handler.getRivers();

}catch(ParserConfigurationExceptione){

e.printStackTrace();

}catch(SAXExceptione){

e.printStackTrace();

}catch(IOExceptione){

e.printStackTrace();

}

Log.d(T,"execfetchRiverFormXmlBySAXusetime="

+(System.currentTimeMillis()-startTime));

returnrivers;

}



privateclassMySaxHandlerextendsDefaultHandler{



privateList<River>rivers=null;



privatebooleanisRiver=false;



privatebooleanisIntrocduce=false;



privatebooleanisImageUrl=false;



privateRiverriver=null;



privateStringTAG="MySaxHandler";



publicMySaxHandler(){

rivers=newArrayList<River>();

}



@Override

publicvoidstartDocument()throwsSAXException{

super.startDocument();

Log.d(TAG,"###startDocument");

}



@Override

publicvoidendDocument()throwsSAXException{

super.endDocument();

Log.d(TAG,"###endDocument");

}



@Override

publicvoidstartElement(Stringuri,StringlocalName,StringqName,

Attributesattributes)throwsSAXException{

super.startElement(uri,localName,qName,attributes);

StringtagName=localName.length()>0?localName:qName;

if(tagName.equals(riverStr)){

isRiver=true;

river=newRiver();

river.setName(attributes.getValue(nameStr));

river.setLength(Integer.parseInt(attributes.getValue(lengthStr)));

}

if(isRiver){

if(tagName.equals(introductionStr)){

isIntrocduce=true;

}elseif(tagName.equals(imageurlStr)){

isImageUrl=true;

}

}



}



@Override

publicvoidendElement(Stringuri,StringlocalName,StringqName)

throwsSAXException{

super.endElement(uri,localName,qName);

//Log.d(TAG,"###endElementuri="+uri+"localName="+

//localName+"qName="+qName);

StringtagName=localName.length()!=0?localName:qName;

if(tagName.equals(riverStr)){

isRiver=false;

rivers.add(river);

}

if(isRiver){

if(tagName.equals(introductionStr)){

isIntrocduce=false;

}elseif(tagName.equals(imageurlStr)){

isImageUrl=false;

}

}

}



@Override

publicvoidcharacters(char[]ch,intstart,intlength)

throwsSAXException{

super.characters(ch,start,length);

if(isIntrocduce){

river.setIntroduction(river.getIntroduction()==null?"":river

.getIntroduction()+newString(ch,start,length));

}elseif(isImageUrl){

river.setImageurl(river.getImageurl()==null?"":river.getImageurl()

+newString(ch,start,length));

}

}



publicList<River>getRivers(){

returnrivers;

}



}

Pull解析方式:

privateList<River>fetchRiverFormXmlByPull(StringfileName){

longstartTime=System.currentTimeMillis();

List<River>rivers=newArrayList<River>();

Riverriver=null;

InputStreaminputStream=null;

//获得解析机对象

XmlPullParserxmlPullParser=Xml.newPullParser();

try{

//得到文件流

inputStream=getAssets().open(fileName);

xmlPullParser.setInput(inputStream,"utf-8");

//获得命名空间(必须调用,否则会抛出异常)

xmlPullParser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES,false);

//Returnsthetypeofthecurrentevent(START_TAG,END_TAG,TEXT,

//etc.)

inteventType=xmlPullParser.getEventType();

while(eventType!=XmlPullParser.END_DOCUMENT){

switch(eventType){

//开始节点<xxx>

caseXmlPullParser.START_TAG:

Stringtag=xmlPullParser.getName();

//Log.d(T,"START_TAG:"+tag);

if(tag.equalsIgnoreCase(riverStr)){

river=newRiver();

river.setName(xmlPullParser.getAttributeValue(null,nameStr));

river.setLength(Integer.parseInt(xmlPullParser.getAttributeValue(null,

lengthStr)));

}elseif(river!=null){

if(tag.equalsIgnoreCase(introductionStr)){

river.setIntroduction(xmlPullParser.nextText());

}elseif(tag.equalsIgnoreCase(imageurlStr)){

river.setImageurl(xmlPullParser.nextText());

}

}

break;

//结束节点</xx>

caseXmlPullParser.END_TAG:

//Log.d(T,"END_TAG:"+xmlPullParser.getName());

if(xmlPullParser.getName().equalsIgnoreCase(riverStr)&&river!=null){

rivers.add(river);

river=null;

}

break;

default:

break;

}

eventType=xmlPullParser.next();

}

}catch(XmlPullParserExceptione){

e.printStackTrace();

}catch(IOExceptione){

e.printStackTrace();

}

Log.d(T,"execfetchRiverFormXmlByPullusetime="

+(System.currentTimeMillis()-startTime));

returnrivers;

}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值