Pull和Sax类似,都是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。因为是基于流的处理,因此Pull和Sax都比较节约内存资源,不会象Dom那样要把所有节点以对橡树的形式展现在内存中。 但Pull比Sax更简明,而且不需要扫描完整个流。
他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。如果在一个XML文档中我们只需要前面一部分数据,但是使用SAX方式或DOM方式会对整个文档进行解析,中间不能终止暂停,尽管XML文档中后面的大部分数据我们其实都不需要解析,因此这样实际上就浪费了处理资源。使用PULL方式正合适。
Pull解析器也提供了类似SAX的事件,开始文档START_DOCUMENT和结束文档END_DOCUMENT,开始元素START_TAG和结束元素END_TAG,遇到元素内容TEXT等,但需要调用next() 方法提取它们(主动提取事件)。
Android系统中和Pull方式相关的包为org.xmlpull.v1. PULL是个开源的项目,源码地址http://www.xmlpull.org/
经常需要使用的类:
XmlPullParserFactory 工厂类,用来创建pull解析器
XmlPullParser pull解析器
XmlPullParserException 异常
XmlSerializer 该类用来将指定的对象转化为XML文档
创建XmlPullParser
创建XmlPullParser方式有两种:
方式一:通过XmlPullParserFactory创建
- XmlPullParserFactoryxpf=XmlPullParserFactory.newInstance();
- sp;XmlPullParserparser=xpf.newPullParser();
方法二:通过Android.util.Xml类
XmlPullParserparser=Xml.newPullParser();
下面开始用Pull解析
解析的流程如下:
(1)取得pull解析器
(2)设置解析器的输入流
(3)产生第一个事件
(4)开始解析
(5)解析结束
解析XML文件如下:
<?xmlversion="1.0"encoding="utf-8"?>
- <rivers>
- <rivername="灵渠"length="605">
- <introduction>
- 灵渠在广西壮族自治区兴安县境内,是世界上最古老的运河之一,有着“世界古代水利建筑明珠”的美誉。灵渠古称秦凿渠、零渠、陡河、兴安运河,于公元前214年凿成通航,距今已2217年,仍然发挥着功用。
- </introduction>
- <imageurl>
- http:
- </imageurl>
- </river>
-
- <rivername="胶莱运河"length="200">
- <introduction>
- 胶莱运河南起黄海灵山海口,北抵渤海三山岛,流经现胶南、胶州、平度、高密、昌邑和莱州等,全长200公里,流域面积达5400平方公里,南北贯穿山东半岛,沟通黄渤两海。胶莱运河自平度姚家村东的分水岭南北分流。南流由麻湾口入胶州湾,为南胶莱河,长30公里。北流由海仓口入莱州湾,为北胶莱河,长100余公里。
- </introduction>
- <imageurl>
- http:
- </imageurl>
- </river>
-
- <rivername="苏北灌溉总渠"length="168">
- 位于淮河下游江苏省北部,西起洪泽湖边的高良涧,流经洪泽,青浦、淮安,阜宁、射阳,滨海等六县(区),东至扁担港口入海的大型人工河道。全长168km。
- </rivers>
解析过程:
privateList<River>parserXMLPULL(InputStreamis)
- {
- List<River>list=null;
- Riverriver=null;
-
-
- //方式一:
- //XmlPullParserparser=Xml.newPullParser();
- //方法二:
- XmlPullParserFactoryxpf= XmlPullParserparser= try{
- xpf=XmlPullParserFactory.newInstance();
- parser=xpf.newPullParser();
- //将XML文件以流的形式加入,并设置XML文件的编码方式
- //parser.setInput(InputStreaninputStream,StringinputEncoding)
- //parser.setInput(Readerreader)
- parser.setInput(is,"UTF-8");
- //此时文档刚初始化,所以解析的位置在文档的开头
- inttype=parser.getEventType();
- //返回类型START_DOCUMENT,END_DOCUMENT,START_TAG,END_TAG,TEXT
- while(type!=XmlPullParser.END_DOCUMENT)
- switch(type)
- caseXmlPullParser.START_DOCUMENT:
- //做一些初始化工作
- list=newArrayList<River>();
- break;
- caseXmlPullParser.START_TAG:
- //rivers
- Stringname=parser.getName();
- if(name.equals("river"))
- {
- StringattrName=parser.getAttributeValue(0);
- intattrLen=Integer.parseInt(parser.getAttributeValue(1));
- river=newRiver();
- river.setName(attrName);
- river.setLength(attrLen);
- }
- if(parser.getName().equals("introduction")&&river!=null)
- Stringintro=parser.nextText();
- river.setIntro(intro);
- }
- if("imageurl".equals(parser.getName())&&river!=null)
- Stringurl=parser.nextText();
- river.setUrl(url);
- break;
- caseXmlPullParser.END_TAG:
- Stringvalue=parser.getName();
- if(value.equals("river")&&river!=null&&list!=//添加对象到list中
- list.add(river);
- type=parser.next();
- }catch(IOExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }catch(XmlPullParserExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- returnlist;
- }
River 类很简单
packagecom.liupan.parse;
- publicclassRiver{
- privateStringname;
- privateintlength;
- privateStringintro;
- privateStringurl;
- publicStringgetName(){
- returnname;
- voidsetName(Stringname){
- this.name=name;
- intgetLength(){
- returnlength;
- voidsetLength(intlength){
- this.length=length;
- publicStringgetIntro(){
- returnintro;
- voidsetIntro(Stringintro){
- this.intro=intro;
- publicStringgetUrl(){
- returnurl;
- voidsetUrl(Stringurl){
- this.url=url;
- }
XmlSerializer类的使用
publicStringcreateXML(Writerwriter,List<River>list)throwsException
- XmlSerializerserial=Xml.newSerializer();
- //设置输出流的位置,本句会抛出异常
- serial.setOutput(writer);
- //以下开始创建XML文件
- serial.startDocument("utf-8",true);
- serial.startTag("","rivers");
- //将list的内容写入XML文件
- if(list!=for(Riverriver:list)
- //创建river标签
- "river");
- //为river标签添加属性name和length
- serial.attribute("","name",river.getName());
- serial.attribute("","length",""+river.getLength());
- "introduction");
- serial.text(river.getIntro());
- serial.endTag("","imageurl");
- serial.text(river.getUrl());
- serial.endTag("","rivers");
- serial.endDocument();
- 刷新输出的缓冲区
- writer.flush();
- //关闭输出流
- writer.close();
- returnwriter.toString();
- }
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|