SAX解析方式

本文详细介绍了SAX解析XML的方式,包括SAX解析的优缺点、事件驱动模式以及在Android中的具体实现步骤。通过实例展示了如何创建ContentHandler,解析XML文档并将其内容映射到自定义实体类中。
摘要由CSDN通过智能技术生成

先新建一个类继承自DefaultHandler

startDocument()方法在开始XML解析的时候调用

startElement()方法在开始解析某个结点的时候调用

characters()方法在获取结点中内容的时候调用

endElement()方法在完成解析某个结点的时候调用

endDocument()方法在完成XML解析的时候调用

先给结点定义一个StringBuilder对象

在startDocument方法对它们进行初始化

开始解析某个结点时,startElement()方法会调用,localName参数记录着当前结点的名字

在解析结点中具体内容时会调用characters()方法,根据结点名进行判断,将解析出的内容添加到哪个StringBuilder对象中

在endElement()方法中判断

目前id…等结点中都可能包括回车或换行符,所以要调用一下trim()方法,

并且还要将StringBuilder的内容清空掉,不然的话会影响下一次内容的读取

先是创建一个SAXParserFactory对象,然后再获取到XMLReader对象

接着将ContentHandler的实例设置到XMLReader中,最后调用parse()方法开始执行解析

package com.jia.networktest;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

/**
 * @author 姚文天
 * 
 */
public class ContentHandler extends DefaultHandler {
	private String nodeName;
	private StringBuilder id;
	private StringBuilder name;
	private StringBuilder version;

	@Override
	public void startDocument() throws SAXException {
		id = new StringBuilder();
		name = new StringBuilder();
		version = new StringBuilder();

	}

	@Override
	public void endDocument() throws SAXException {

	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// 记录当前结点名
		nodeName = localName;
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		if ("app".equals(localName)) {
			Log.d("jia", "id is---------------->" + id.toString().trim());
			Log.d("jia", "name is----------------->" + name.toString().trim());
			Log.d("jia", "version is---------------->"
					+ version.toString().trim());
			// 最后要将StringBuilder清空掉
			id.setLength(0);
			name.setLength(0);
			version.setLength(0);
		}

	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// 根据当前的结点名判断将内容添加到哪一个StringBuilder对象中
		if ("id".equals(nodeName)) {
			id.append(ch, start, length);
		} else if ("name".equals(nodeName)) {
			name.append(ch, start, length);
		} else if ("version".equals(nodeName)) {
			version.append(ch, start, length);
		}
	}

}

private void parseXMLWithSAX(String response) {
				try {
					SAXParserFactory factory = SAXParserFactory.newInstance();
					XMLReader xmlReader = factory.newSAXParser().getXMLReader();
					ContentHandler handler = new ContentHandler();
					// 将ContentHandler的实例设置到XMLReader中
					xmlReader.setContentHandler(handler);
					// 开始执行解析
					xmlReader
							.parse(new InputSource(new StringReader(response)));
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}

解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析。

DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了。

  优点:整个文档读入内存,方便操作:支持修改、删除和重现排列等多种功能。

  缺点:将整个文档读入内存中,保留了过多的不需要的节点,浪费内存和空间。

  使用场合:一旦读入文档,还需要多次对文档进行操作,并且在硬件资源充足的情况下(内存,CPU)。

为了解决DOM解析存在的问题,就出现了SAX解析。其特点为:

  优点:不用实现调入整个文档,占用资源少。尤其在嵌入式环境中,如android,极力推荐使用SAX解析。

  缺点:不像DOM解析一样将文档长期驻留在内存中,数据不是持久的。如果事件过后没有保存数据,数据就会丢失。

  使用场合:机器有性能限制。

SAX解析XML文档采用事件驱动模式。什么是事件驱动模式?它将XML文档转换成一系列的事件,由单独的事件处理器来决定如何处理。

基于事件驱动的处理模式主要是基于事件源和事件处理器(或者叫监听器)来工作的。一个可以产生事件的对象叫做事件源,而一个可以针对事件做出响应的对象就被叫做事件处理器。

在SAX接口中,事件源是org.xml.sax包中的XMLReader,他通过parse()方法开始解析XML文档,并根据文档内容产生事件。而事件处理器则是org.xml.sax包中的ContentHandler、DTDHandler、ErrorHandler,以及EntityResolver这四个接口。他们分别处理事件源在解析过程中产生不同类的事件(其中DTDHandler为解析文档DTD时所用)。详细介绍如下表:

在上述四个接口中,最重要的就是ContentHandler这个接口,下面是对这个接口方法的说明:

复制代码
//设置一个可以定位文档内容事件发生位置的定位器对象

public void setDocumentLocator(Locator locator)

//用于处理文档解析开始事件

public void startDocument()throws SAXException

//处理元素开始事件,从参数中可以获得元素所在名称空间的uri,元素名称,属性类表等信息

public void startElement(String namespacesURI , String localName , String qName , Attributes atts) throws SAXException

//处理元素结束事件,从参数中可以获得元素所在名称空间的uri,元素名称等信息

public void endElement(String namespacesURI , String localName , String qName) throws SAXException

//处理元素的字符内容,从参数中可以获得内容

public void characters(char[] ch , int start , int length) throws SAXException
复制代码

这里再介绍下XMLReader中的方法。

//注册处理XML文档解析事件ContentHandler
public void setContentHandler(ContentHandler handler)

//开始解析一个XML文档
public void parse(InputSorce input) throws SAXException


SAX实现实体解析的步骤:

在android中使用SAX是有迹可循的,完全可以按照下面的方法就可以轻松找到xml里的tag,然后得到想要的内容。具体实现步骤如下:

(一)第一步:新建一个工厂类SAXParserFactory,代码如下:

SAXParserFactory factory = SAXParserFactory.newInstance();

(二)第二步:让工厂类产生一个SAX的解析类SAXParser,代码如下:

SAXParser parser = factory.newSAXParser();

(三)第三步:从SAXPsrser中得到一个XMLReader实例,代码如下:

XMLReader reader = parser.getXMLReader();

(四)第四步:把自己写的handler注册到XMLReader中,一般最重要的就是ContentHandler,代码如下:

RSSHandler handler = new RSSHandler();
reader.setContentHandler(handler);

(五)第五步:将一个xml文档或者资源变成一个java可以处理的InputStream流后,解析正式开始,代码如下:

parser.parse(is);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值