`

android xml解析 - sax

阅读更多
android 2.3 sdk提供的与sax解析相关的类和接口
它们主要存在与以下的这些包中:
org.xml.sax
org.xml.sax.ext
org.xml.sax.helpers
javax.xml.parsers
android.sax

sax相关介绍
sax存在两个版本1和2,1已经过时了,所以与其相关的api基本也可以忽略(除非是处理遗留代码),现在的话主要使用2.0的sax。

sax是一种推式解析器,所有的事件都是解析器主动发给我们的。它会根据事件的类型,去调用规定好的事件方法。

sax通过以下的接口来规定了一系列的事件方法:
org.xml.sax包中:
ContentHandler,主要包含了在遇到起始标签,结束标签,内容等事件时会调用的方法
ErrorHandler,主要包含了在解析xml时,出现错误时会调用的方法
DTDHandler,主要包含了解析dtd文档时,遇到notation、未解析的entity resolver等事件时,会调用的方法

org.xml.sax.ext包中:
LexicalHandler,主要包含了在遇到comment(注释),dtd declaration(dtd声明),CDATA等事件时会调用的方法
DeclHandler,用在dtd文件中,主要包含了在遇到dtd文档中的相应事件时调用的方法
以下三个很少会用到,这里不做介绍。
Attributes2
EntityResolver2
Locator2

还需要知道的一个类org.xml.sax.helpers.DefaultHandler:
该类可以看作是一个适配器类,就是它实现了ContentHandler, DTDHandler, EntityResover, ErrorHandler,但是在其内部什么也没做,仅仅是为了方便我们使用。
一般的话我们会继承这个类来写事件处理代码,而不是去实现接口。

sax解析一般数据
解析的数据和前一篇中提到的一样:
<root><data><create>8</create><fans>4</fans><home>9</home><mentions>0</mentions><private>0</private></data><errcode>0</errcode><msg>ok</msg><ret>0</ret></root>
<!-- 便于阅读的格式 -->  
<root>  
    <data>  
        <create>8</create>  
        <fans>4</fans>  
        <home>9</home>  
        <mentions>0</mentions>  
        <private>0</private>  
    </data>  
    <errcode>0</errcode>  
    <msg>ok</msg>  
    <ret>0</ret>  
</root>  

// 解析器创建
SAXParserFactory factory = SAXParserFactory.newInstance();
// 配置要创建的parser的特性,配置特性的方法在android api中是无法调用的(主要是考虑到它是移动设备,某些特性太耗性能了)
// 像腾迅微博返回的xml数据可以交换关闭dtd验证(提升3倍的速度)和命名空间
// factory.setValidating(false); // 在android上默认为false
// factory.setNamespaceAware(false); // 在android上默认为false
// 创建解析器
SAXParser parser = factory.newSAXParser();
InputSource source = new InputSource("d:/test.xml");
MyDefaultHandler handler = new MyDefaultHandler();
parser.parse(source, handler);


// 事件处理类
public class MyDefaultHandler extends DefaultHandler {
	@Override
	public void startDocument() throws SAXException {
		// 文档开始
	}
	
	@Override
	public void endDocument() throws SAXException {
		// 文档结束
	}

	private static final int root = 0;
	private static final int data = 1;
	private static final int create = 2;
	private static final int fans = 3;
	private static final int home = 4;
	private static final int mentions = 5;
	private static final int privates = 6;

	int currentTag = -1;
	StringBuilder text = null;
	
	// lName(local name)只有在开启命名空间(setNamespaceAware时才有值),而qName是一直有值的
	// 注意在android上,默认命名空间为false,但它的lName总是有值,qName总是没值(如:yd:phone,lName会返回phone)
	@Override
	public void startElement(String uri, String lName, String qName, Attributes attrs)
			throws SAXException {
		if ("root".equals(qName)) {
			currentTag = root;
		} else if ("data".equals(qName)) {
			currentTag = data;
		} else if ("create".equals(qName)) {
			currentTag = create;
			text = new StringBuilder();
		} else if ("fans".equals(qName)) {
			currentTag = fans;
			text = new StringBuilder();
		} else if ("home".equals(qName)) {
			currentTag = home;
			text = new StringBuilder();
		} else if ("mentions".equals(qName)) {
			currentTag = mentions;
			text = new StringBuilder();
		} else if ("private".equals(qName)) {
			currentTag = privates;
			text = new StringBuilder();
		} else {
			// unknow element, just pass
		}
	}

	// lName(local name 没有前缀的名称)只有在开启命名空间(setNamespaceAware时才有值),而qName是一直有值的
	// 注意在android上,默认命名空间为false,但它的lName总是有值,qName总是没值(如:yd:phone,lName会返回phone)
	@Override
	public void endElement(String uri, String lName, String qName)
			throws SAXException {
		switch (currentTag) {
		case root:
			// 该元素结束后,马上就是endDocument了。
			break;

		case data:
			currentTag = root;
			break;

		case create:
			// setCreate(text.toString());
			currentTag = data;
			break;

		case fans:
			// setFans(text.toString());
			currentTag = data;
			break;

		case home:
			// setHome(text.toString());
			currentTag = data;
			break;

		case mentions:
			// setMentions(text.toString());
			currentTag = data;
			break;

		case privates:
			// setPrivates(text.toString());
			currentTag = data;
			break;

		default:
			// unknow element, just pass
		}
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		switch (currentTag) {
		case create:
		case fans:
		case home:
		case mentions:
		case privates:
			// get the text
			text.append(new String(ch, start, length));
			break;

		case root:
		case data:
		default:
			// have no interesting text to get
		}
	}
}
分享到:
评论
1 楼 lsz10122 2011-12-30  
                         

相关推荐

Global site tag (gtag.js) - Google Analytics