XML 解析--SAX

来源:互联网 发布:福州市第一中学 知乎 编辑:程序博客网 时间:2024/06/02 21:59

最近项目中客户端与服务端申请资源使用了xml,所以这里整理一下使用SAX解析XML的过程。


SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。

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

大多数SAX实现都会产生以下类型的事件:
在文档的开始和结束时触发文档处理事件。
在文档内每一XML元素接受解析的前后触发元素事件。
任何元数据通常都由单独的事件交付。
在处理文档的DTD或Schema时产生DTD或Schema事件。
产生错误事件用来通知主机应用程序解析错误。

触发的顺序:

一:sax中DefaultHandler解析XML总体过程

        startDocument--->具体读到某个node(非根node和根node)的解析过程 --->endDocument 。

二:DefaultHandler 解析XML 的非根node是按顺序的 四步 (不管当前node是ElementNode[可有属性]还是TextNode):

        第一步:startElement. 

        第二步 :  characters     

        第三步 :  endElement   

        第四步 :  characters     

三:DefaultHandler 解析XML 的根node是按顺序的 三步 :

        第一步:startElement.

        第二步 :  characters    

        第三步 :  endElement 


需要解析的XML:
OK---------------------<PCforecast><Result><Status>0</Status><ErrorCode/><ErrorMessage>ログインしました。</ErrorMessage></Result></PCforecast>---------------------NG---------------------<PCforecast><Result><Status>9</Status><ErrorCode>ASME7004E</ErrorCode><ErrorMessage>乗務員IDまたパスワードは間違いましたので、ログインできません。</ErrorMessage></Result></PCforecast>---------------------
需要返回的对象ResultEntity:
public class ResultEntity {    private String status;    private String errorCode;    private String errorMessage;    public String getStatus() {        return status;    }    public void setStatus(String status) {        this.status = status;    }    public String getErrorCode() {        return errorCode;    }    public void setErrorCode(String errorCode) {        this.errorCode = errorCode;    }    public String getErrorMessage() {        return errorMessage;    }    public void setErrorMessage(String errorMessage) {        this.errorMessage = errorMessage;    }}

再写一个Handler类,用来解析XML为ResultEntity对象:
public class LoginSaxHandler extends DefaultHandler {    //声明一个ResultEntity类型的变量    private ResultEntity resultEntity;    //声明一个字符串变量    private String content;    /**     * LoginSaxHandler的构造方法     */    public LoginSaxHandler() {    }    public ResultEntity getResultEntity() {        return this.resultEntity;    }    /**     * 当SAX解析器解析到XML文档开始时,会调用的方法     */    @Override    public void startDocument() throws SAXException {        super.startDocument();    }    /**     * 当SAX解析器解析到XML文档结束时,会调用的方法     */    @Override    public void endDocument() throws SAXException {        super.endDocument();    }    /**     * 当SAX解析器解析到某个属性值时,会调用的方法     * 其中参数ch记录了这个属性值的内容     */    @Override    public void characters(char[] ch, int start, int length)            throws SAXException {        super.characters(ch, start, length);        content = new String(ch, start, length);    }    /**     * 当SAX解析器解析到某个元素开始时,会调用的方法     * 其中localName记录的是元素属性名     */    @Override    public void startElement(String uri, String localName, String qName,                             Attributes attributes) throws SAXException {        super.startElement(uri, localName, qName, attributes);        if ("Result".equals(localName)) {            resultEntity = new ResultEntity(); //新建ResultEntity对象        }    }    /**     * 当SAX解析器解析到某个元素结束时,会调用的方法     * 其中localName记录的是元素属性名     */    @Override    public void endElement(String uri, String localName, String qName)            throws SAXException {        super.endElement(uri, localName, qName);        if ("Status".equals(localName)) {            resultEntity.setStatus(content);        } else if ("ErrorCode".equals(localName)) {            resultEntity.setErrorCode(content);        } else if ("ErrorMessage".equals(localName)) {            resultEntity.setErrorMessage(content);        }    }}
最后在代码中使用这个解析类:
private ResultEntity parseXML(String response) {        LoginSaxHandler contentHandler = new LoginSaxHandler();        try {            InputStream inputStream = new ByteArrayInputStream(response.getBytes("utf-8"));            // 创建一个SAXParserFactory            SAXParserFactory factory = SAXParserFactory.newInstance();            // ②创建SAX解析器            SAXParser parser = factory.newSAXParser();            // ③将XML解析处理器分配给解析器            // ④对文档进行解析,将每个事件发送给处理器。            parser.parse(inputStream, contentHandler);            inputStream.close();            ResultEntity entity = contentHandler.getResultEntity();            return entity;        } catch (Exception e) {            Log.e(TAG, e.getMessage());            return null;        }    }
reponse是从网络获取到的内容。
解析Log:
startElement: localName : PCforecast qName : PCforecastcharacters:                 startElement: localName : Result qName : Resultcharacters:                     startElement: localName : Status qName : Statuscharacters: 0endElement: localName : Status qName : Statuscharacters:                     startElement: localName : ErrorCode qName : ErrorCodeendElement: localName : ErrorCode qName : ErrorCodecharacters:                     startElement: localName : ErrorMessage qName : ErrorMessagecharacters: ログインしました。endElement: localName : ErrorMessage qName : ErrorMessagecharacters:                 endElement: localName : Result qName : Resultcharacters:             endElement: localName : PCforecast qName : PCforecast

如果XML内是一组数据,可以参考一下博客:
http://blog.csdn.net/bear_huangzhen/article/details/24477327




0 0
原创粉丝点击