Android使用Pull方法解析XML文件的方法
2023-06-13 09:14:54 时间
Pull解析方法给应用程序完全的控制文档该怎么样被解析。Android中对Pull方法提供了支持的API,主要是
复制代码代码如下:
org.xmlpull.v1.XmlPullParser;
org.xmlpull.v1.XmlPullParserFactory;
二个类,其中主要使用的是XmlPullParser,XmlPullParserFactory是一个工厂,用于构建XmlPullParser对象。
应用程序通过调用XmlPullParser.next()等方法来产生Event,然后再处理Event。可以看到它与Push方法的不同,Push方法是由Parser自己主动产生Event,回调给应用程序。而Pull方法是主动的调用Parser的方法才能产生事件。
假如XML中的语句是这样的:"<authorcountry="UnitedStates">JamesElliott</author>",author是TAG,country是ATTRIBUTE,"JamesElliott"是TEXT。
要想解析文档先要构建一个XmlPullParser对象
finalXmlPullParserFactoryfactory=XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
finalXmlPullParserparser=factory.newPullParser();
Pull解析是一个遍历文档的过程,每次调用next(),nextTag(),nextToken()和nextText()都会向前推进文档,并使Parser停留在某些事件上面,但是不能倒退。
然后把文档设置给Parser
parser.setInput(newStringReader("<authorcountry=\"UnitedStates\">JamesElliott</author>");
这时,文档刚被初始化,所以它应该位于文档的开始,事件应该是START_DOCUMENT,可以通过XmlPullParser.getEventType()来获取。然后调用next()会产生
START_TAG,这个事件告诉应用程序一个标签已经开始了,调用getName()会返回"author";再next()会产生
TEXT事件,调用getText()会返回"JamesElliott",再next(),会产生
END_TAG,这个告诉你一个标签已经处理完了,再next(),会产生
END_DOCUMENT,它告诉你整个文档已经处理完成了。
除了next()外,nextToken()也可以使用,只不过它会返回更加详细的事件,比如COMMENT,CDSECT,DOCDECL,ENTITY等等非常详细的信息。如果程序得到比较底层的信息,可以用nextToken()来驱动并处理详细的事件。需要注意一点的是TEXT事件是有可能返回空白的WhiteSpaces比如换行符或空格等。
另外有二个非常实用的方法nextTag()和nextText()
nextTag()--首先它会忽略WhiteSpaces,如果可以确定下一个是START_TAG或END_TAG,就可以调用nextTag()直接跳过去。通常它有二个用处:当START_TAG时,如果能确定这个TAG含有子TAG,那么就可以调用nextTag()产生子标签的START_TAG事件;当END_TAG时,如果确定不是文档结尾,就可以调用nextTag()产生下一个标签的START_TAG。在这二种情况下如果用next()会有TEXT事件,但返回的是换行符或空白符。
nextText()--它只能在START_TAG时调用。当下一个元素是TEXT时,TEXT的内容会返回;当下一个元素是END_TAG时,也就是说这个标签的内容为空,那么空字串返回;这个方法返回后,Parser会停在END_TAG上。比如:
<author>JamesElliott</author>
<author></author>
<author/>
当START_TAG时,调用nextText(),依次返回:
""(empty)
""(empty)
这个方法在处理没有子标签的标签时很有用。比如:
<title>WhatIsHibernate</title>
<author>JamesElliott</author>
<category>Web</category>
就可以用以下代码来处理:
while(eventType!=XmlPullParser.END_TAG){
switch(eventType){
caseXmlPullParser.START_TAG:
tag=parser.getName();
finalStringcontent=parser.nextText();
Log.e(TAG,tag+":["+content+"]");
eventType=parser.nextTag();
break;
default:
break;
}
}
这就要比用next()来处理方便多了,可读性也大大的加强了。
最后附上一个解析XML的实例Android程序
importjava.io.IOException;
importjava.io.InputStream;
importorg.xmlpull.v1.XmlPullParser;
importorg.xmlpull.v1.XmlPullParserException;
importorg.xmlpull.v1.XmlPullParserFactory;
importandroid.util.Log;
publicclassRssPullParserextendsRssParser{
privatefinalStringTAG=FeedSettings.GLOBAL_TAG;
privateInputStreammInputStream;
publicRssPullParser(InputStreamis){
mInputStream=is;
}
publicvoidparse()throwsReaderBaseException,XmlPullParserException,IOException{
if(mInputStream==null){
thrownewReaderBaseException("noinputsource,didyouinitializethisclasscorrectly?");
}
finalXmlPullParserFactoryfactory=XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
finalXmlPullParserparser=factory.newPullParser();
parser.setInput(mInputStream);
inteventType=parser.getEventType();
if(eventType!=XmlPullParser.START_DOCUMENT){
thrownewReaderBaseException("Notstartingwith"start_document"");
}
eventType=parseRss(parser);
if(eventType!=XmlPullParser.END_DOCUMENT){
thrownewReaderBaseException("notendingwith"end_document",doyoufinishparsing?");
}
if(mInputStream!=null){
mInputStream.close();
}else{
Log.e(TAG,"inputstreamisnull,XmlPullParserclosedit??");
}
}
/**
*ParsingtheXmldocument.CurrenttypemustbeStart_Document.
*Aftercallingthis,ParserispositionedatEND_DOCUMENT.
*@paramparser
*@returneventend_document
*@throwsXmlPullParserException
*@throwsReaderBaseException
*@throwsIOException
*/
privateintparseRss(XmlPullParserparser)throwsXmlPullParserException,ReaderBaseException,IOException{
inteventType=parser.getEventType();
if(eventType!=XmlPullParser.START_DOCUMENT){
thrownewReaderBaseException("notstartingwith"start_document",isthisanewdocument?");
}
Log.e(TAG,"startingdocument,areyouawareofthat!");
eventType=parser.next();
while(eventType!=XmlPullParser.END_DOCUMENT){
switch(eventType){
caseXmlPullParser.START_TAG:{
Log.e(TAG,"starttag:""+parser.getName()+""");
finalStringtagName=parser.getName();
if(tagName.equals(RssFeed.TAG_RSS)){
Log.e(TAG,"startinganRSSfeed<<");
finalintattrSize=parser.getAttributeCount();
for(inti=0;i<attrSize;i++){
Log.e(TAG,"attr""+parser.getAttributeName(i)+"="+parser.getAttributeValue(i)+""");
}
}elseif(tagName.equals(RssFeed.TAG_CHANNEL)){
Log.e(TAG,"\tstartinganChannel<<");
parseChannel(parser);
}
break;
}
caseXmlPullParser.END_TAG:{
Log.e(TAG,"endtag:""+parser.getName()+""");
finalStringtagName=parser.getName();
if(tagName.equals(RssFeed.TAG_RSS)){
Log.e(TAG,">>edninganRSSfeed");
}elseif(tagName.equals(RssFeed.TAG_CHANNEL)){
Log.e(TAG,"\t>>endinganChannel");
}
break;
}
default:
break;
}
eventType=parser.next();
}
Log.e(TAG,"endofdocument,itisover");
returnparser.getEventType();
}
/**
*Parseachannel.MUSTbestarttagofanchannel,otherwiseexceptionthrown.
*ParamXmlPullParser
*Aftercallingthisfunction,parserispositionedatEND_TAGofChannel.
*returnendtagofachannel
*@throwsXmlPullParserException
*@throwsReaderBaseException
*@throwsIOException
*/
privateintparseChannel(XmlPullParserparser)throwsXmlPullParserException,ReaderBaseException,IOException{
inteventType=parser.getEventType();
StringtagName=parser.getName();
if(eventType!=XmlPullParser.START_TAG||!RssFeed.TAG_CHANNEL.equals(tagName)){
thrownewReaderBaseException("notstartwith"starttag",isthisastartofachannel?");
}
Log.e(TAG,"\tstarting"+tagName);
eventType=parser.nextTag();
while(eventType!=XmlPullParser.END_TAG){
switch(eventType){
caseXmlPullParser.START_TAG:{
finalStringtag=parser.getName();
if(tag.equals(RssFeed.TAG_IMAGE)){
parseImage(parser);
}elseif(tag.equals(RssFeed.TAG_ITEM)){
parseItem(parser);
}else{
finalStringcontent=parser.nextText();
Log.e(TAG,tag+":["+content+"]");
}
//nowitSHOULDbeatEND_TAG,ensureit
if(parser.getEventType()!=XmlPullParser.END_TAG){
thrownewReaderBaseException("notendingwith"endtag",didyoufinishparsingsubitem?");
}
eventType=parser.nextTag();
break;
}
default:
break;
}
}
Log.e(TAG,"\tending"+parser.getName());
returnparser.getEventType();
}
/**
*Parseimageinachannel.
*Precondition:positionmustbeatSTART_TAGandtagMUSTbe"image"
*Postcondition:positionisEND_TAGof"/image"
*@throwsIOException
*@throwsXmlPullParserException
*@throwsReaderBaseException
*/
privateintparseImage(XmlPullParserparser)throwsXmlPullParserException,IOException,ReaderBaseException{
inteventType=parser.getEventType();
Stringtag=parser.getName();
if(eventType!=XmlPullParser.START_TAG||!RssFeed.TAG_IMAGE.equals(tag)){
thrownewReaderBaseException("notstartwith"starttag",isthisastartofanimage?");
}
Log.e(TAG,"\t\tstartingimage"+tag);
eventType=parser.nextTag();
while(eventType!=XmlPullParser.END_TAG){
switch(eventType){
caseXmlPullParser.START_TAG:
tag=parser.getName();
Log.e(TAG,tag+":["+parser.nextText()+"]");
//nowitSHOULDbeatEND_TAG,ensureit
if(parser.getEventType()!=XmlPullParser.END_TAG){
thrownewReaderBaseException("notendingwith"endtag",didyoufinishparsingsubitem?");
}
eventType=parser.nextTag();
break;
default:
break;
}
}
Log.e(TAG,"\t\tendingimage"+parser.getName());
returnparser.getEventType();
}
/**
*Parseaniteminachannel.
*Precondition:positionmustbeatSTART_TAGandtagMUSTbe"item"
*Postcondition:positionisEND_TAGof"/item"
*@throwsIOException
*@throwsXmlPullParserException
*@throwsReaderBaseException
*/
privateintparseItem(XmlPullParserparser)throwsXmlPullParserException,IOException,ReaderBaseException{
inteventType=parser.getEventType();
Stringtag=parser.getName();
if(eventType!=XmlPullParser.START_TAG||!RssFeed.TAG_ITEM.equals(tag)){
thrownewReaderBaseException("notstartwith"starttag",isthisastartofanitem?");
}
Log.e(TAG,"\t\tstarting"+tag);
eventType=parser.nextTag();
while(eventType!=XmlPullParser.END_TAG){
switch(eventType){
caseXmlPullParser.START_TAG:
tag=parser.getName();
finalStringcontent=parser.nextText();
Log.e(TAG,tag+":["+content+"]");
//nowitSHOULDbeatEND_TAG,ensureit
if(parser.getEventType()!=XmlPullParser.END_TAG){
thrownewReaderBaseException("notendingwith"endtag",didyoufinishparsingsubitem?");
}
eventType=parser.nextTag();
break;
default:
break;
}
}
Log.e(TAG,"\t\tending"+parser.getName());
returnparser.getEventType();
}
}
相关文章
- android对文件进行加密
- Android 编译_android线程
- Android保存图片到相册(适配android 10以下及以上)
- 【Android 安全】DEX 加密 ( 代理 Application 开发 | 加载 dex 文件 | 使用反射获取方法创建本应用的 dexElements | 各版本创建 dex 数组源码对比 )
- 【Android 应用开发】Android 工程修改包名流程 ( 修改 applicationId | 修改 package | 修改 R 资源引用 | 修改 BuildConfig 引用 )
- 【Android 逆向】Android 系统文件分析 ( /proc/ 目录文件分析 | 记录系统和进程信息 | version 内核版本信息文件 )
- 【Android 逆向】Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )
- 【错误记录】编译 Android 版本的 ijkplayer 报错 ( ./init-android.sh: 第 37 行: cd: android/contrib/: 没有那个文件或目录 )
- 【Android Gradle 插件】自定义 Gradle 任务 ⑯ ( 从任务容器 TaskContainer 中搜索 Gradle 任务 | 压缩 packageDebug 任务输出文件 )
- 【Android OpenCV】Visual Studio 创建支持 OpenCV 库的 CMake 工程 ③ ( CMake 工程中配置 OpenCV 库文件 | 拷贝 OpenCV 函数库文件 )
- Android下的Linux指令集详解手机开发
- 将文件放到Android模拟器的SD卡中的两种解决方法
- Android字符串资源文件format方法使用实例
- android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
- Android实现上传文件功能的方法
- Android实现下载文件功能的方法