sax解析

前面说到了pull解析和dom解析、自然少不了sax解析、而在这里、我将sax解析写成接口、方便更具扩展性、


比如要处理类似格式的xml文件:

<?xml version="1.0" encoding="utf-8"?>
<!-- 结果信息 -->
<result>
<resultCode>1</resultCode>
<resultMessage>结果信息</resultMessage>
</result>
<!-- 下面是xml数据 -->


结果信息实体类:

public class ResultInfo {
	
	private String resultCode;
	private String resultMessage="";
	
	public static final String RESULT_CODE_OK = "1";
	public static final String RESULT_CODE_ERROR = "0";
	
	//-------------------------------
	
	public ResultInfo(){
		
	}
	
	public ResultInfo(String resultCode,String resultMessage){
		
		this.resultCode = resultCode;
		this.resultMessage = resultMessage;
	}
	
	//-------------------------------
	
	public String getResultCode() {
		return resultCode;
	}

	public void setResultCode(String resultCode) {
		this.resultCode = resultCode;
	}

	public String getResultMessage() {
		return resultMessage;
	}

	public void setResultMessage(String resultMessage) {
		this.resultMessage = resultMessage;
	}
	
	//-------------------------------

	
	@Override
	public String toString() {
		return "resultInfo:["+resultCode+" "+resultMessage +"]";
	}

上面的resultCode也可以直接写成int类型的、只不过在下面需要转换下、


接着写一个抽象的 AbstractHandler去继承 DefaultHandler

public abstract class AbstractHandler extends DefaultHandler{
	
	protected final String CLAZZ = "AbstractHandler";

	//-----------------------------------------
	public static final String TAG_NAME_RESULT_INFO = "result";
	public static final String TAG_NAME_RESULT_CODE = "resultCode";
	public static final String TAG_NAME_RESULT_MESSAGE = "resultMessage";
	//-----------------------------------------
	
	private String tagName;
	private String content;
	
	private ResultInfo resultInfo;

	//-----------------------------------------
	
	public String getTagName() {
		return tagName;
	}
	public void setTagName(String tagName) {
		this.tagName = tagName;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public ResultInfo getResultInfo() {
		return resultInfo;
	}
	public void setResultInfo(ResultInfo resultInfo) {
		this.resultInfo = resultInfo;
	}
	//-----------------------------------------
	
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
	}
	//-----------------------------------------
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
	}
	
	//-----------------------------------------
	
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		super.startElement(uri, localName, qName, attributes);
		this.tagName = localName;
		
		if(TAG_NAME_RESULT_INFO.equalsIgnoreCase(localName)){
			resultInfo = new ResultInfo();
		}else if(TAG_NAME_PAGE_INFO.equalsIgnoreCase(localName)){
			pageInfo = new PageInfo();
		}else{
			startElements(uri, localName, qName, attributes);
		}
	}
	//-----------------------------------------
	
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		super.characters(ch, start, length);
		
		content = new String(ch,start,length);
			try{
				if(!TextUtils.isEmpty(content.trim())){
					if(TAG_NAME_RESULT_CODE.equalsIgnoreCase(tagName)){
						resultInfo.setResultCode(content);
					}else if(TAG_NAME_RESULT_MESSAGE.equalsIgnoreCase(tagName)){
						resultInfo.setResultMessage(content);
					}else{
						characterss(ch, start, length);
					}
				}
				LogUtils.logI(tagName+"\t-------\t"+content);
			}catch (NumberFormatException e) {
				LogUtils.logE(CLAZZ, "数字格式化错误!");
			}catch (Exception e) {
				LogUtils.logE(CLAZZ, e.getMessage());
				e.printStackTrace();
			}
	}
	
	
	//-----------------------------------------
	
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		super.endElement(uri, localName, qName);
		
		endElements(uri, localName, qName);
	
	}
	
	
	//-----------------------------------------
	
	public abstract void startElements(String uri, String localName, String qName, Attributes attributes);
	
	public abstract void characterss(char[] ch, int start, int length);
	
	public abstract void endElements(String uri,String localName,String qName);
}

在这里之所以将AbstractHandler写成抽象类、就是为了更具有扩展性的去处理上面的xml标记的<!-- 下面是xml数据 -->这些可扩展的未知数据、


接着写个默认的ResultHandler继承AbstractHandler去实现抽象方法:

public class ResultHandler extends AbstractHandler{

	@Override
	public void startElements(String uri, String localName, String qName, Attributes attributes) {
		
	}

	@Override
	public void characterss(char[] ch, int start, int length) {
		
	}

	@Override
	public void endElements(String uri, String localName, String qName) {
		
	}

}

以上只是针对于上面风格的xml文件写了个处理器Handler、接着下面还需通过SAXParserFactory得到一个XMLReader、不过在这里、得先写个XmlParser接口


XmlParser接口:

public interface XmlParser {
	
	/**
	 * XML解析回调接口
	 */
	public interface XmlParserCallback{
		
		void onFinish();
		
		void onError(String error);
	}
	
	public void parse(InputSource inputSource);
	
	public void parse(String response);

}


然后写个XmlParserImpl实现XmlParser接口:

public class XmlParserImpl implements XmlParser{
	
	//-----------------------------------------
	
	private AbstractHandler handler;
	private XmlParserCallback callback;
	
	//-----------------------------------------
	
	public XmlParserImpl(AbstractHandler handler,XmlParserCallback callback){
		if(null!=handler){
			this.handler = handler;
		}else{
			this.handler = new ResultHandler();
		}
		this.callback = callback;
	}

	//-----------------------------------------
	
	@Override
	public void parse(String response){
		parse(new InputSource(new StringReader(response)));
	}
	
	@Override
	public void parse(InputSource inputSource) {
		
		try {
			SAXParserFactory factory = SAXParserFactory.newInstance();
			XMLReader xmlReader = factory.newSAXParser().getXMLReader();
			xmlReader.setContentHandler(handler);
			xmlReader.parse(inputSource);
			
			
			ResultInfo resultInfo = handler.getResultInfo();
			
			if(ResultInfo.RESULT_CODE_OK.equals(resultInfo.getResultCode())){
				callback.onFinish();
			}else{
				callback.onError("解析结果码:"+resultInfo.getResultCode()+"\n结果信息:"+resultInfo.getResultMessage());
			}
		}catch(Exception e){
			callback.onError("XML解析出错!");
			e.printStackTrace();
		}
	}

}

这样、其实一个可扩展性的sax解析就完成了、只要直接new一个XmlParserImpl就可以直接解析了、比如就解析那个默认的xml文件:

final ResultHandler resultHandler = new ResultHandler();
XmlParser xmlParser = new XmlParserImpl(resultHandler , new XmlParserCallback() {
	
	@Override
	public void onFinish() {
		//表示成功、结果码为1
		System.out.println(resultHandler.getResultInfo().toString());//结果信息

	}
	
	@Override
	public void onError(String error) {
		
		
	}
});
xmlParser.parse(xml);//xml以InputStream或String都行


若需扩展只要写个类去实现AbstractHandler、根据节点来解析扩展的数据即可、

ps:像这样半封装式的写个sax解析接口并实现它、总结一些共性的是不是很好呢、



转载于:https://my.oschina.net/jenly/blog/748063

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值