Android中利用SAX解析XML文件(转)

1.什么是SAX

答:Android平台解析XML主要是使用SAX这么一个标准。日常开发中有两种常见方式解析XML,一种是SAX;另一种就是DOM(文档对象模型),把XML文档看做一棵树,有根节点,子节点和叶节点,首先要把XML文档全部装载在内存中,然后解析成一棵树,在树上进行相应的操作,好处就是操作简单方便,缺点就是当处理文档比较大,性能上就会存在一些问题。

SAX是逐行的扫描文档,可一边扫描一边解析,可以在解析文档的任意时刻来停止这次解析。缺点是操作起来稍微复杂一些,通过SAX往XML文档中添加或删除内容比较费劲。

2.SAX基本原理

答:SAX(Simple API for XML),既是指一种接口,也是指一个软件包。

作为接口,SAX是事件驱动型XML解析的一个标准接口

SAX是一个标准,做出这个标准就是为了解析XML文档

SAX的工作原理简单的说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素(element)开始与结束,文档结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。(以事件为驱动的解析的过程)

大多数SAX实现都会产生以下类型的事件:

在文档的开始和结束时触发文档处理事件。

在文档内每一个XML元素接受解析的前后触发元素事件。

任何元数据通常都由单独的事件交付。

在处理文档的DTD或Schema时产生DTD或Schema事件。

产生错误事件用来通知主机应用程序解析错误。

SAX模型

Android中利用SAX解析XML文件(转)

解析文档过程

对于如下文档:

<doc>

<para>Hello,world! </para>

</doc>

在解析文档的过程中会产生如下一系列事件

start document (1)创建事件处理程序

start element:doc (2)创建SAX解析器

start element:para (3)将事件处理程序分配给解析器

characters: Hello,world! (4)对文档进行解析,将每个事件发送给处理程序

end element:para

end element:doc

end document

SAX常用接口

答:ContentHandler接口

ContentHandler是java类包中一个特殊的SAX接口,位于org.xml.sax包中。该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件,比如文档的开头和结束,元素的开头和结束,以及元素中的字符数据等事件。当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件。

ContentHandler接口的方法有以下几种:

void startDocument(); void endDocument();

void startElement(String uri,String localName,String qName,Attributes arrs);

void endElement(String uri,String localName,String qName);

void character(char[] ch,int start,int length);//得到标签之间的内容

其中,uri表示得到当前正在解析的标签的命名空间;localName是不带前缀的标签值,qName是带前缀的标签值;Attributes表示得到标签所有属性。

注意:要非常小心这里的character方法。

Android中利用SAX解析XML文件(转)

在图中标明2的地方会调用characters(char[] ch, int start, int length)方法,不要以为那里是空白,Sax解析器可不那么认为,Sax解析器会把它认为是一个TextNode。但是这个空白不是我们想要的数据,我们是想要<name>节点下的文本信息。这就要定义一个记录当上一节点的名称的TAG,在characters(.....)方法中,判断当前节点是不是name

XMLActivity.java

  1. packagecom.examples.xml;
  2. importjava.io.IOException;
  3. importjava.io.StringReader;
  4. importjavax.xml.parsers.ParserConfigurationException;
  5. importjavax.xml.parsers.SAXParserFactory;
  6. importorg.xml.sax.InputSource;
  7. importorg.xml.sax.SAXException;
  8. importorg.xml.sax.XMLReader;
  9. importcom.examples.utils.HttpDownloader;
  10. importandroid.app.Activity;
  11. importandroid.os.Bundle;
  12. importandroid.view.View;
  13. importandroid.view.View.OnClickListener;
  14. importandroid.widget.Button;
  15. publicclassXMLActivityextendsActivity{
  16. /**Calledwhentheactivityisfirstcreated.*/
  17. privateButtonparseBtn;
  18. @Override
  19. publicvoidonCreate(BundlesavedInstanceState){
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.main);
  22. parseBtn=(Button)findViewById(R.id.parseBtn);
  23. parseBtn.setOnClickListener(newparseBtnListener());
  24. }
  25. classparseBtnListenerimplementsOnClickListener
  26. {
  27. @Override
  28. publicvoidonClick(Viewv){
  29. HttpDownloaderhttpdown=newHttpDownloader();
  30. Stringresult=httpdown.download("http://202.193.82.14:8080/vao1500/test.xml");
  31. System.out.println(result);
  32. //创建一个SAXParserFactory
  33. SAXParserFactorysaxParser=SAXParserFactory.newInstance();
  34. try{
  35. XMLReaderxmlReader=saxParser.newSAXParser().getXMLReader();
  36. //为xmlReader设置内容处理器
  37. xmlReader.setContentHandler(newMyContentHandler());
  38. //开始解析文件
  39. xmlReader.parse(newInputSource(newStringReader(result)));
  40. }catch(Exceptione){
  41. e.printStackTrace();
  42. }
  43. }
  44. }
  45. }


MyContentHandler.java

  1. packagecom.examples.xml;
  2. importorg.xml.sax.Attributes;
  3. importorg.xml.sax.SAXException;
  4. importorg.xml.sax.helpers.DefaultHandler;
  5. publicclassMyContentHandlerextendsDefaultHandler
  6. {
  7. StringsName,sSex,sAddress,sStatus,sMoney;
  8. StringtagName;
  9. @Override
  10. publicvoidstartDocument()throwsSAXException{
  11. System.out.println("start------------->");
  12. }
  13. @Override
  14. publicvoidendDocument()throwsSAXException{
  15. System.out.println("end------------->");
  16. }
  17. @Override
  18. publicvoidstartElement(Stringuri,StringlocalName,StringqName,
  19. Attributesattributes)throwsSAXException{
  20. tagName=localName;
  21. if(localName.equals("worker"))
  22. {
  23. //获得标签全部属性
  24. for(inti=0;i<attributes.getLength();i++)
  25. {
  26. System.out.println(attributes.getLocalName(i)+"="+attributes.getValue(i));
  27. }
  28. }
  29. }
  30. @Override
  31. publicvoidendElement(Stringuri,StringlocalName,StringqName)
  32. throwsSAXException{
  33. //在worker标签解析之后,会打印出所有得到的数据
  34. if(localName.equals("worker"))
  35. {
  36. this.printout();
  37. }
  38. tagName=null;
  39. }
  40. @Override
  41. publicvoidcharacters(char[]ch,intstart,intlength)
  42. throwsSAXException{
  43. if(tagName!=null)
  44. {
  45. if(tagName.trim().equalsIgnoreCase("name"))
  46. {
  47. sName=newString(ch,start,length);
  48. }elseif(tagName.trim().equalsIgnoreCase("sex"))
  49. {
  50. sSex=newString(ch,start,length);
  51. }elseif(tagName.trim().equalsIgnoreCase("address"))
  52. {
  53. sAddress=newString(ch,start,length);
  54. }elseif(tagName.trim().equalsIgnoreCase("status"))
  55. {
  56. sStatus=newString(ch,start,length);
  57. }
  58. elseif(tagName.trim().equalsIgnoreCase("money"))
  59. {
  60. sMoney=newString(ch,start,length);
  61. }
  62. }
  63. }
  64. publicvoidprintout()
  65. {
  66. System.out.print("name:");
  67. System.out.println(sName);
  68. System.out.print("sex:");
  69. System.out.println(sSex);
  70. System.out.print("address:");
  71. System.out.println(sAddress);
  72. System.out.print("status:");
  73. System.out.println(sStatus);
  74. System.out.print("money:");
  75. System.out.println(sMoney);
  76. }
  77. }

  78. 原作者:http://blog.****.net/xutaogenlanqiu/article/details/6612925