Android提高之XML解析与生成实例详解
程序员文章站
2022-11-05 14:48:39
本文实例讲述了使用sax来解析xml。通常来说在android里面可以使用sax和dom,dom需要把整个xml文件读入内存再解析,比较消耗内存,而sax是基于事件驱动的处...
本文实例讲述了使用sax来解析xml。通常来说在android里面可以使用sax和dom,dom需要把整个xml文件读入内存再解析,比较消耗内存,而sax是基于事件驱动的处理方式,可以在各节点触发回调函数,不过sax适合节点结构简单的xml文档,复杂的xml文档在后期的节点深度处理会有点麻烦。
本文要解析的test.xml文件如下:
<?xml version="1.0" encoding="utf-8"?> <test> <title>testsax</title> <content aa="1" bb="2"> <name>hellogv</name> <url>http://blog.csdn.net/hellogv</url> </content> </test>
解析如上xml的结果如下图所示:
使用sax解析,需要定义saxparserfactory(使应用程序能够配置和获取基于 sax 的解析器以解析 xml 文档),saxparser(从各种输入源解析 xml),xmlreader(使用回调函数读取 xml 文档),其中xmlreader是个关键。xmlreader可以为解析xml定义各种回调函数,“条件符合”的时候触发这些回调函数。
saxparserfactory factory = saxparserfactory.newinstance(); saxparser parser = factory.newsaxparser(); xmlreader reader = parser.getxmlreader(); reader.setcontenthandler(handler); reader.parse(new inputsource(testsax.this.getresources() .openrawresource(r.raw.test)));
在这段代码里,xmlreader就调用继承defaulthandler的saxhandler。defaulthandler已实现contenthandler, dtdhandler, entityresolver, errorhandler等接口,包含常见读取xml的操作,具体请看下面的saxhandler.java源码。
最终生成xml的结果如下图所示:
上图是读取各节点之后,使用xmlserializer重新组合并输出xml字符串。
本文的main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnsax" android:text="使用sax解析xml"></button> <button android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="生成xml" android:id="@+id/btnoutput"></button> <edittext android:text="@+id/edittext01" android:id="@+id/edittext01" android:layout_width="fill_parent" android:layout_height="fill_parent"></edittext> </linearlayout>
saxhandler.java的源码如下:
package com.testsax; import java.util.arraylist; import org.xml.sax.attributes; import org.xml.sax.saxexception; import org.xml.sax.helpers.defaulthandler; import android.util.log; public class saxhandler extends defaulthandler{ private arraylist<string> keys = new arraylist<string>();//保存字段名称 private arraylist<object> values = new arraylist<object>();//保存值 @override public void startdocument() throws saxexception { super.startdocument(); } @override public void enddocument() throws saxexception { super.enddocument(); } @override public void startelement(string uri, string localname, string qname, attributes attributes) throws saxexception { //保存开始标记 keys.add("starttag"); values.add(localname); log.e("starttag",localname); //保存属性值 for ( int i = 0; i < attributes.getlength(); i++ ){ keys.add("attr"); string[] str=new string[2]; str[0]=attributes.getlocalname(i); str[1]=attributes.getvalue(i); values.add(str); log.e("attr",str[0]+"="+str[1]); } } @override public void endelement(string uri, string localname, string qname) throws saxexception { //保存结束标记 keys.add("endtag"); values.add(localname); log.e("endtag",localname); } @override public void characters(char[] ch, int start, int length) throws saxexception { string value = new string(ch, start, length); value = value.trim(); if (value.length() == 0) return; keys.add("text"); values.add(value); log.e("text",value); } public arraylist<string> getkeys() { return keys; } public arraylist<object> getvalues() { return values; } }
testsax.java的源码如下:
package com.testsax; import java.io.stringwriter; import javax.xml.parsers.saxparser; import javax.xml.parsers.saxparserfactory; import org.xml.sax.inputsource; import org.xml.sax.xmlreader; import org.xmlpull.v1.xmlserializer; import android.app.activity; import android.os.bundle; import android.util.xml; import android.view.view; import android.widget.button; import android.widget.edittext; public class testsax extends activity { /** called when the activity is first created. */ button btnsax, btnoutput; edittext memo; saxhandler handler = new saxhandler(); @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); btnsax = (button) this.findviewbyid(r.id.btnsax); btnsax.setonclicklistener(new clickevent()); btnoutput = (button) this.findviewbyid(r.id.btnoutput); btnoutput.setonclicklistener(new clickevent()); memo = (edittext) this.findviewbyid(r.id.edittext01); } class clickevent implements view.onclicklistener { @override public void onclick(view v) { if (v == btnsax) {//解析xml,并保存标记,属性等值 try { saxparserfactory factory = saxparserfactory.newinstance(); saxparser parser = factory.newsaxparser(); xmlreader reader = parser.getxmlreader(); reader.setcontenthandler(handler); reader.parse(new inputsource(testsax.this.getresources() .openrawresource(r.raw.test))); } catch (exception ee) {} } else if (v == btnoutput) {//生成xml try { xmlserializer serializer = xml.newserializer(); stringwriter writer = new stringwriter(); try { serializer.setoutput(writer); serializer.startdocument("utf-8",true); for(int i=0;i<handler.getkeys().size();i++) { if(handler.getkeys().get(i).equals("starttag")) { serializer.starttag("", (string) handler.getvalues().get(i)); } else if(handler.getkeys().get(i).equals("attr")){ string[] str= (string[]) handler.getvalues().get(i); serializer.attribute("",str[0],str[1]); } else if(handler.getkeys().get(i).equals("text")) serializer.text((string)handler.getvalues().get(i)); else if(handler.getkeys().get(i).equals("endtag")) { serializer.endtag("", (string) handler.getvalues().get(i)); } } serializer.enddocument(); string text=writer.tostring(); text=text.replace("><", ">/r/n<"); memo.settext(text);//输出到文本框 } catch (exception e) { throw new runtimeexception(e); } } catch (exception e) {} } } } }
感兴趣的读者可以自己动手调试运行一下本实例代码,希望能对大家的android项目开发起到参考借鉴作用。