XML 解析--SAX
2016-07-20 15:10
393 查看
最近项目中客户端与服务端申请资源使用了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:
再写一个Handler类,用来解析XML为ResultEntity对象:
解析Log:
如果XML内是一组数据,可以参考一下博客:
http://blog.csdn.net/bear_huangzhen/article/details/24477327
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 : PCforecast characters: startElement: localName : Result qName : Result characters: startElement: localName : Status qName : Status characters: 0 endElement: localName : Status qName : Status characters: startElement: localName : ErrorCode qName : ErrorCode endElement: localName : ErrorCode qName : ErrorCode characters: startElement: localName : ErrorMessage qName : ErrorMessage characters: ログインしました。 endElement: localName : ErrorMessage qName : ErrorMessage characters: endElement: localName : Result qName : Result characters: endElement: localName : PCforecast qName : PCforecast
如果XML内是一组数据,可以参考一下博客:
http://blog.csdn.net/bear_huangzhen/article/details/24477327
相关文章推荐
- Android—ContentProvider读取系统联系人
- iOS开发UI篇-自定义CALayer
- 应用优化
- 直接用编译器按ctrl+F5运行和Release、Debug下双击运行结果不一样
- java中读取配置文件的方法
- XSS攻击
- 一代记忆
- ThreadLocal误区解密
- 移动网络手机抓包分享
- Javascript 基础之Date对象
- Linux makefile 教程,简单粗暴,2小时学习makefile
- 磁盘 I/O 优化
- Web压力测试工具-Apache Bench
- 如何把HTML标记分类
- Redis 集群
- Window下sqlite的安装
- Oracle 查看一个表对应的主键和外键的约束关系
- linux 下部署 tomcat
- Java 调整格式日志输出
- POJ 3984 迷宫问题