Android提高第七篇之XML解析与生成
本文来自http://blog.csdn.net/hellogv/,引用必须注明出处!
本文使用SAX来解析XML,在Android里面可以使用SAX和DOM,DOM需要把整个XML文件读入内存再解析,比较消耗内存,而SAX基于事件驱动的处理方式,可以在各节点触发回调函数,不过SAX适合节点结构简单的XML文档,复杂的XML文档在后期的节点深度处理会有点麻烦。
本文要解析的test.xml文件如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <test>
- <title>testSAX</title>
- <contentaa="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定义各种回调函数,“条件符合”的时候触发这些回调函数。
- SAXParserFactoryfactory=SAXParserFactory.newInstance();
- SAXParserparser=factory.newSAXParser();
- XMLReaderreader=parser.getXMLReader();
- reader.setContentHandler(handler);
- reader.parse(newInputSource(testSAX.this.getResources()
- .openRawResource(R.raw.test)));
在这段代码里,XMLReader就调用继承DefaultHandler的SAXHandler。DefaultHandler已实现ContentHandler, DTDHandler, EntityResolver, ErrorHandler等接口,包含常见读取XML的操作,具体请看下面的SAXHandler.java源码。
生成XML的结果如下:
上图是读取各节点之后,使用XmlSerializer重新组合并输出XML字符串。
本文的main.xml代码如下:
- <?xmlversion="1.0"encoding="utf-8"?>
- <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <Buttonandroid:layout_height="wrap_content"
- android:layout_width="fill_parent"android:id="@+id/btnSAX"
- android:text="使用SAX解析XML"></Button>
- <Buttonandroid:layout_height="wrap_content"
- android:layout_width="fill_parent"android:text="生成XML"android:id="@+id/btnOutput"></Button>
- <EditTextandroid:text="@+id/EditText01"android:id="@+id/EditText01"
- android:layout_width="fill_parent"android:layout_height="fill_parent"></EditText>
- </LinearLayout>
SAXHandler.java的源码如下:
- packagecom.testSAX;
- importjava.util.ArrayList;
- importorg.xml.sax.Attributes;
- importorg.xml.sax.SAXException;
- importorg.xml.sax.helpers.DefaultHandler;
- importandroid.util.Log;
- publicclassSAXHandlerextendsDefaultHandler{
- privateArrayList<String>keys=newArrayList<String>();//保存字段名称
- privateArrayList<Object>values=newArrayList<Object>();//保存值
- @Override
- publicvoidstartDocument()throwsSAXException{
- super.startDocument();
- }
- @Override
- publicvoidendDocument()throwsSAXException{
- super.endDocument();
- }
- @Override
- publicvoidstartElement(Stringuri,StringlocalName,StringqName,
- Attributesattributes)throwsSAXException{
- //保存开始标记
- keys.add("startTag");
- values.add(localName);
- Log.e("startTag",localName);
- //保存属性值
- for(inti=0;i<attributes.getLength();i++){
- keys.add("Attr");
- String[]str=newString[2];
- str[0]=attributes.getLocalName(i);
- str[1]=attributes.getValue(i);
- values.add(str);
- Log.e("Attr",str[0]+"="+str[1]);
- }
- }
- @Override
- publicvoidendElement(Stringuri,StringlocalName,StringqName)
- throwsSAXException{
- //保存结束标记
- keys.add("endTag");
- values.add(localName);
- Log.e("endTag",localName);
- }
- @Override
- publicvoidcharacters(char[]ch,intstart,intlength)
- throwsSAXException{
- Stringvalue=newString(ch,start,length);
- value=value.trim();
- if(value.length()==0)
- return;
- keys.add("text");
- values.add(value);
- Log.e("text",value);
- }
- publicArrayList<String>GetKeys()
- {
- returnkeys;
- }
- publicArrayList<Object>GetValues()
- {
- returnvalues;
- }
- }
testSAX.java的源码如下:
- packagecom.testSAX;
- importjava.io.StringWriter;
- importjavax.xml.parsers.SAXParser;
- importjavax.xml.parsers.SAXParserFactory;
- importorg.xml.sax.InputSource;
- importorg.xml.sax.XMLReader;
- importorg.xmlpull.v1.XmlSerializer;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.util.Xml;
- importandroid.view.View;
- importandroid.widget.Button;
- importandroid.widget.EditText;
- publicclasstestSAXextendsActivity{
- /**Calledwhentheactivityisfirstcreated.*/
- ButtonbtnSAX,btnOutput;
- EditTextmemo;
- SAXHandlerhandler=newSAXHandler();
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btnSAX=(Button)this.findViewById(R.id.btnSAX);
- btnSAX.setOnClickListener(newClickEvent());
- btnOutput=(Button)this.findViewById(R.id.btnOutput);
- btnOutput.setOnClickListener(newClickEvent());
- memo=(EditText)this.findViewById(R.id.EditText01);
- }
- classClickEventimplementsView.OnClickListener{
- @Override
- publicvoidonClick(Viewv){
- if(v==btnSAX){//解析XML,并保存标记,属性等值
- try{
- SAXParserFactoryfactory=SAXParserFactory.newInstance();
- SAXParserparser=factory.newSAXParser();
- XMLReaderreader=parser.getXMLReader();
- reader.setContentHandler(handler);
- reader.parse(newInputSource(testSAX.this.getResources()
- .openRawResource(R.raw.test)));
- }catch(Exceptionee){}
- }
- elseif(v==btnOutput){//生成XML
- try{
- XmlSerializerserializer=Xml.newSerializer();
- StringWriterwriter=newStringWriter();
- try{
- serializer.setOutput(writer);
- serializer.startDocument("UTF-8",true);
- for(inti=0;i<handler.GetKeys().size();i++)
- {
- if(handler.GetKeys().get(i).equals("startTag"))
- {
- serializer.startTag("",(String)handler.GetValues().get(i));
- }
- elseif(handler.GetKeys().get(i).equals("Attr")){
- String[]str=(String[])handler.GetValues().get(i);
- serializer.attribute("",str[0],str[1]);
- }
- elseif(handler.GetKeys().get(i).equals("text"))
- serializer.text((String)handler.GetValues().get(i));
- elseif(handler.GetKeys().get(i).equals("endTag"))
- {
- serializer.endTag("",(String)handler.GetValues().get(i));
- }
- }
- serializer.endDocument();
- Stringtext=writer.toString();
- text=text.replace("><",">/r/n<");
- memo.setText(text);//输出到文本框
- }catch(Exceptione){
- thrownewRuntimeException(e);
- }
- }catch(Exceptione){}
- }
- }
- }
- }