Android提高第七篇之XML解析与生成

本文来自http://blog.csdn.net/hellogv/,引用必须注明出处!

本文使用SAX来解析XML,在Android里面可以使用SAX和DOM,DOM需要把整个XML文件读入内存再解析,比较消耗内存,而SAX基于事件驱动的处理方式,可以在各节点触发回调函数,不过SAX适合节点结构简单的XML文档,复杂的XML文档在后期的节点深度处理会有点麻烦。

本文要解析的test.xml文件如下:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <test>
  3. <title>testSAX</title>
  4. <contentaa="1"bb="2">
  5. <name>hellogv</name>
  6. <url>http://blog.csdn.net/hellogv</url>
  7. </content>
  8. </test>

解析如上XML的结果如下:

Android提高第七篇之XML解析与生成

使用SAX解析,需要定义SAXParserFactory(使应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档),SAXParser(从各种输入源解析 XML),XMLReader(使用回调函数读取 XML 文档),其中XMLReader是个关键。XMLReader可以为解析XML定义各种回调函数,“条件符合”的时候触发这些回调函数。

  1. SAXParserFactoryfactory=SAXParserFactory.newInstance();
  2. SAXParserparser=factory.newSAXParser();
  3. XMLReaderreader=parser.getXMLReader();
  4. reader.setContentHandler(handler);
  5. reader.parse(newInputSource(testSAX.this.getResources()
  6. .openRawResource(R.raw.test)));

在这段代码里,XMLReader就调用继承DefaultHandler的SAXHandler。DefaultHandler已实现ContentHandler, DTDHandler, EntityResolver, ErrorHandler等接口,包含常见读取XML的操作,具体请看下面的SAXHandler.java源码。

生成XML的结果如下:

Android提高第七篇之XML解析与生成

上图是读取各节点之后,使用XmlSerializer重新组合并输出XML字符串。

本文的main.xml代码如下:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <Buttonandroid:layout_height="wrap_content"
  6. android:layout_width="fill_parent"android:id="@+id/btnSAX"
  7. android:text="使用SAX解析XML"></Button>
  8. <Buttonandroid:layout_height="wrap_content"
  9. android:layout_width="fill_parent"android:text="生成XML"android:id="@+id/btnOutput"></Button>
  10. <EditTextandroid:text="@+id/EditText01"android:id="@+id/EditText01"
  11. android:layout_width="fill_parent"android:layout_height="fill_parent"></EditText>
  12. </LinearLayout>

SAXHandler.java的源码如下:

  1. packagecom.testSAX;
  2. importjava.util.ArrayList;
  3. importorg.xml.sax.Attributes;
  4. importorg.xml.sax.SAXException;
  5. importorg.xml.sax.helpers.DefaultHandler;
  6. importandroid.util.Log;
  7. publicclassSAXHandlerextendsDefaultHandler{
  8. privateArrayList<String>keys=newArrayList<String>();//保存字段名称
  9. privateArrayList<Object>values=newArrayList<Object>();//保存值
  10. @Override
  11. publicvoidstartDocument()throwsSAXException{
  12. super.startDocument();
  13. }
  14. @Override
  15. publicvoidendDocument()throwsSAXException{
  16. super.endDocument();
  17. }
  18. @Override
  19. publicvoidstartElement(Stringuri,StringlocalName,StringqName,
  20. Attributesattributes)throwsSAXException{
  21. //保存开始标记
  22. keys.add("startTag");
  23. values.add(localName);
  24. Log.e("startTag",localName);
  25. //保存属性值
  26. for(inti=0;i<attributes.getLength();i++){
  27. keys.add("Attr");
  28. String[]str=newString[2];
  29. str[0]=attributes.getLocalName(i);
  30. str[1]=attributes.getValue(i);
  31. values.add(str);
  32. Log.e("Attr",str[0]+"="+str[1]);
  33. }
  34. }
  35. @Override
  36. publicvoidendElement(Stringuri,StringlocalName,StringqName)
  37. throwsSAXException{
  38. //保存结束标记
  39. keys.add("endTag");
  40. values.add(localName);
  41. Log.e("endTag",localName);
  42. }
  43. @Override
  44. publicvoidcharacters(char[]ch,intstart,intlength)
  45. throwsSAXException{
  46. Stringvalue=newString(ch,start,length);
  47. value=value.trim();
  48. if(value.length()==0)
  49. return;
  50. keys.add("text");
  51. values.add(value);
  52. Log.e("text",value);
  53. }
  54. publicArrayList<String>GetKeys()
  55. {
  56. returnkeys;
  57. }
  58. publicArrayList<Object>GetValues()
  59. {
  60. returnvalues;
  61. }
  62. }

testSAX.java的源码如下:

  1. packagecom.testSAX;
  2. importjava.io.StringWriter;
  3. importjavax.xml.parsers.SAXParser;
  4. importjavax.xml.parsers.SAXParserFactory;
  5. importorg.xml.sax.InputSource;
  6. importorg.xml.sax.XMLReader;
  7. importorg.xmlpull.v1.XmlSerializer;
  8. importandroid.app.Activity;
  9. importandroid.os.Bundle;
  10. importandroid.util.Xml;
  11. importandroid.view.View;
  12. importandroid.widget.Button;
  13. importandroid.widget.EditText;
  14. publicclasstestSAXextendsActivity{
  15. /**Calledwhentheactivityisfirstcreated.*/
  16. ButtonbtnSAX,btnOutput;
  17. EditTextmemo;
  18. SAXHandlerhandler=newSAXHandler();
  19. @Override
  20. publicvoidonCreate(BundlesavedInstanceState){
  21. super.onCreate(savedInstanceState);
  22. setContentView(R.layout.main);
  23. btnSAX=(Button)this.findViewById(R.id.btnSAX);
  24. btnSAX.setOnClickListener(newClickEvent());
  25. btnOutput=(Button)this.findViewById(R.id.btnOutput);
  26. btnOutput.setOnClickListener(newClickEvent());
  27. memo=(EditText)this.findViewById(R.id.EditText01);
  28. }
  29. classClickEventimplementsView.OnClickListener{
  30. @Override
  31. publicvoidonClick(Viewv){
  32. if(v==btnSAX){//解析XML,并保存标记,属性等值
  33. try{
  34. SAXParserFactoryfactory=SAXParserFactory.newInstance();
  35. SAXParserparser=factory.newSAXParser();
  36. XMLReaderreader=parser.getXMLReader();
  37. reader.setContentHandler(handler);
  38. reader.parse(newInputSource(testSAX.this.getResources()
  39. .openRawResource(R.raw.test)));
  40. }catch(Exceptionee){}
  41. }
  42. elseif(v==btnOutput){//生成XML
  43. try{
  44. XmlSerializerserializer=Xml.newSerializer();
  45. StringWriterwriter=newStringWriter();
  46. try{
  47. serializer.setOutput(writer);
  48. serializer.startDocument("UTF-8",true);
  49. for(inti=0;i<handler.GetKeys().size();i++)
  50. {
  51. if(handler.GetKeys().get(i).equals("startTag"))
  52. {
  53. serializer.startTag("",(String)handler.GetValues().get(i));
  54. }
  55. elseif(handler.GetKeys().get(i).equals("Attr")){
  56. String[]str=(String[])handler.GetValues().get(i);
  57. serializer.attribute("",str[0],str[1]);
  58. }
  59. elseif(handler.GetKeys().get(i).equals("text"))
  60. serializer.text((String)handler.GetValues().get(i));
  61. elseif(handler.GetKeys().get(i).equals("endTag"))
  62. {
  63. serializer.endTag("",(String)handler.GetValues().get(i));
  64. }
  65. }
  66. serializer.endDocument();
  67. Stringtext=writer.toString();
  68. text=text.replace("><",">/r/n<");
  69. memo.setText(text);//输出到文本框
  70. }catch(Exceptione){
  71. thrownewRuntimeException(e);
  72. }
  73. }catch(Exceptione){}
  74. }
  75. }
  76. }
  77. }