zoukankan      html  css  js  c++  java
  • 安卓SAX解析XML文件

    XML文件经常使用的解析方式有DOM解析,SAX解析。

    一、Sax

    SAX(simpleAPIforXML)是一种XML解析的替代方法。

    相比于DOM。SAX是一种速度更快,更有效的方法。

    它逐行扫描文档。一边扫描一边解析。

    并且相比于DOM。SAX能够在解析文档的随意时刻停止解析,但不论什么事物都有其相反的一面,对于SAX来说就是操作复杂。

    SAX解析XML文档採用事件驱动模式。什么是事件驱动模式?它将XML文档转换成一系列的事件。由单独的事件处理器来决定怎样处理。

    基于事件驱动的处理模式主要是基于事件源和事件处理器(或者叫监听器)来工作的。一个能够产生事件的对象叫做事件源。而一个能够针对事件做出响应的对象就被叫做事件处理器。

    在SAX接口中,事件源是org.xml.sax包中的XMLReader,他通过parse()方法開始解析XML文档,并依据文档内容产生事件。而事件处理器则是org.xml.sax包中的ContentHandler、DTDHandler、ErrorHandler,以及EntityResolver这四个接口。他们分别处理事件源在解析过程中产生不同类的事件(当中DTDHandler为解析文档DTD时所用)。具体介绍例如以下表:

    在上述四个接口中。最重要的就是ContentHandler这个接口,以下是对这个接口方法的说明:

    实现一个ContentHandler一般要一下几个步骤:

    1、声明一个类,继承DefaultHandler。DefaultHandler是一个基类。这个类里面简单实现了一个ContentHandler。

    我们仅仅须要重写里面的方法就可以。

    2、重写 startDocument() 和 endDocument(),一般解析将正式解析之前的一些初始化工资放到startDocument()里面,收尾的工作放到endDocument()里面。

    3、重写startElement(),XML解析器遇到XML里面的tag时就会调用这个函数。常常在这个函数内是通过localName俩进行推断而操作一些数据。

    4、重写characters()方法,这是一个回调方法。解析器运行完startElement()后,解析完节点的内容后就会运行这种方法,而且參数ch[]就是节点的内容。这个样例里我们依据currentstate的不同。来推断当前那个tag的内容。并放到合适的实体类中。

    5、重写endElement()方法,这种方法与startElement()相相应,解析完一个tag节点后,运行这种方法。


    //设置一个能够定位文档内容事件发生位置的定位器对象

    public void setDocumentLocator(Locator locator)

    //用于处理文档解析開始事件

    public void startDocument()throws SAXException

    //处理元素開始事件,从參数中能够获得元素所在名称空间的uri,元素名称。属性类表等信息

    public void startElement(String namespacesURI , String localName , String qName , Attributes atts) throws SAXException

    //处理元素结束事件,从參数中能够获得元素所在名称空间的uri,元素名称等信息

    public void endElement(String namespacesURI , String localName , String qName) throws SAXException

    //处理元素的字符内容,从參数中能够获得内容

    public void characters(char[] ch , int start , int length) throws SAXException
    复制代码

    这里再介绍下XMLReader中的方法。

    //注冊处理XML文档解析事件ContentHandler
    public void setContentHandler(ContentHandler handler)

    //開始解析一个XML文档
    public void parse(InputSorce input) throws SAXException


    二、SAX实现解析的步骤:

    在android中使用SAX是有迹可循的,全然能够依照以下的方法就能够轻松找到xml里的tag,然后得到想要的内容。详细实现过程例如以下:

    (一)第一步:新建一个工厂类SAXParserFactory,代码例如以下:

    SAXParserFactory factory = SAXParserFactory.newInstance();

    (二)第二步:让工厂类产生一个SAX的解析类SAXParser,代码例如以下:

    SAXParser parser = factory.newSAXParser();

    (三)第三步:从SAXPsrser中得到一个XMLReader实例。代码例如以下:

    XMLReader reader = parser.getXMLReader();
    ---能够不要reader将第五步改动为parser.parse(xmlfile。handler);

    (四)第四步:把自己写的handler注冊到XMLReader中。一般最重要的就是ContentHandler,代码例如以下:

    RSSHandler handler = new RSSHandler();
    reader.setContentHandler(handler);

    (五)第五步:将一个xml文档或者资源变成一个java能够处理的InputStream流后,解析正式開始,代码例如以下:

    reader.parse(inputstream);

    上面几个步骤中,最重要、最关键的就是第四步,handler的实现。

    详细例如以下所看到的:

     SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();
    XMLReader reader = parser.getXMLReader();
    RSSHandler handler = new RSSHandler();
    reader.setContentHandler(handler);
    InputSource is = new InputSource(this.getClassLoader().getResourceAsStream("xmlFile.xml"));//取得本地xml文件
    reader.parse(is);
    
    
    或者:
     	   SAXParserFactory factory = SAXParserFactory.newInstance();
    SAXParser parser = factory.newSAXParser();

    RSSHandler handler = new RSSHandler();

    reader.parse(xmlFile,handler);


    以下通过一个RSS解析的样例说明handler的实现:

    我们先是自己见一个rss的xml文档。实现本地解析。新建的rss文档例如以下:

    复制代码
    <?

    xml version="1.0" encoding="UTF-8"?

    >
    <channel>
    <title>RSS 解析练习</title>
    <description>hehehaha</description>
    <link>http://www.cnblogs.com/felix-hua/</link>
    <language>zh-cn</language>

    <item>
    <title><![CDATA[头条]]></title>
    <link>http://mc.cz001.com.cn/images/menu/23_active.png</link>
    <category>0</category>
    <description>描写叙述具体信息的</description>
    <pubDate>2012-01-09</pubDate>
    </item>

    复制代码

    建好后,我们命名为rssxml.xml,然后放到项目的根文件夹下:

    以下就是最最重要的地方了,建立自己的ContentHandler.看以下的代码:

    RSSHandler.java

    复制代码
    package com.sax.org.handler;

    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;

    import com.sax.org.entity.RSSFeed;
    import com.sax.org.entity.RSSItem;

    public class RSSHandler extends DefaultHandler{

    String currentTag;
        String currentValue;
         
    @Override
    public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.startDocument();
    }

    @Override
    public void endDocument() throws SAXException {
    // TODO Auto-generated method stub

    }

    @Override
    public void startElement(String uri, String localName, String qName,
    Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub
    	currentTag=localName;
    }

    @Override
    public void endElement(String uri, String localName, String qName)
    throws SAXException {
    // TODO Auto-generated method stub
               currentTag=localName;

    }

    @Override
    public void characters(char[] ch, int start, int length)
    throws SAXException {
    // TODO Auto-generated method stub
            currentValue = new String(ch, start, length).trim();//从当前 String 对象移除全部前导空白字符和尾部空白字符。
    //操作
    }
    }
    开启解析仅仅须要依据上面步骤进行就可以。
  • 相关阅读:
    大数据【一】集群配置及ssh免密认证
    安卓测试【三】adb简单命令及monkey使用
    安卓测试【二】eclipse离线安装ADT
    初始化对象的知识细节
    安卓测试【一】android sdk环境变量配置
    自动化测试用例排序(三个算法随机、贪心、额外贪心)
    java实现文件复制粘贴功能
    Javsssist用InsertAt()方法对语句插桩
    Javassist进行方法插桩
    JUnit手动设计测试方法以及与Randoop的自动生成测试的比较
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7258520.html
Copyright © 2011-2022 走看看