您的位置:首页 > 其它

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:
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: