androidのSAX方式解析XML

androidのSAX方式解析XML

第二种方式:SAX解析器:

  SAX(Simple API for XML)解析器是一种基于事件的解析器,事件驱动的流式解析方式是,从文件的开始顺序解析到文档的结束,不可暂停或倒退。它的核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法,一个事件就可以得到处理。在事件源调用事件处理器中特定方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的事件信息来决定自己的行为。  

  SAX解析器的优点是解析速度快,占用内存少。非常适合在Android移动设备中使用。

SAX的工作原理:SAX的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

  在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并产生事件。事件处理器是org.xml.sax包中ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口。XMLReader通过相应事件处理器注册方法setXXXX()来完成的与ContentHander、DTDHander、ErrorHandler,以及EntityResolver这4个接口的连接。

常用的SAX接口和类:

Attrbutes:用于得到属性的个数、名字和值。  

ContentHandler:定义与文档本身关联的事件(例如,开始和结束标记)。大多数应用程序都注册这些事件。

DTDHandler:定义与DTD关联的事件。它没有定义足够的事件来完整地报告DTD。如果需要对DTD进行语法分析,请使用可选的DeclHandler。

DeclHandler是SAX的扩展。不是所有的语法分析器都支持它。

EntityResolver:定义与装入实体关联的事件。只有少数几个应用程序注册这些事件。

ErrorHandler:定义错误事件。许多应用程序注册这些事件以便用它们自己的方式报错。

DefaultHandler:它提供了这些接LI的缺省实现。在大多数情况下,为应用程序扩展DefaultHandler并覆盖相关的方法要比直接实现一个接口更容易。

接下来看下代码

package com.wyl.example;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

//定义了本实例的主要Activity
public class MainActivity extends Activity {
	private TextView mTvShow;  	//显示结果
	private Button mBtnSax;	// Sax解析

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 得到布局中的控件
		findView();
		// 绑定控件事件
		setListener();
	}

	private void setListener() {
		// 添加事件
		mBtnSax.setOnClickListener(myListener);
	}

	private void findView() {
		// 绑定控件
		mTvShow = (TextView) findViewById(R.id.textview);
		mBtnSax = (Button) findViewById(R.id.btnSAX);
	}

	private OnClickListener myListener = new OnClickListener() {

		@Override
		public void onClick(View v) {
			// 1、获取当前工程中的people.xml的文件流
			InputStream inputStream = MainActivity.class.getClassLoader()
					.getResourceAsStream("people.xml");
			//定义Person对象
			List<Person> persons = null;
			mTvShow.setText("");
			switch (v.getId()) {
			case R.id.btnSAX:  //SAX解析
				mTvShow.setText("SAX:");
				try {
					//使用SAXPersonService服务进行xml解析
					persons = SAXPersonService.readXml(inputStream);
				} catch (ParserConfigurationException e) {
					e.printStackTrace();
				} catch (SAXException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				break;
			default:
				break;
			}
			//显示解析结果
			for (Person person : persons) {
				mTvShow.setText(mTvShow.getText().toString() + "\n" + person.toString());
			}
		}
	};
}

然后定义一个person类

package com.wyl.example;

//解析用的实体 Person类
public class Person {
	// 学生id
	private Integer id;
	// 学生名字
	private String name;
	// 学生年龄
	private Short age;

	public Person() {
		super();
	}

	public Person(Integer id, String name, Short age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Short getAge() {
		return age;
	}

	public void setAge(Short age) {
		this.age = age;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return "id = " + id + "name = " + name + "age = " + age;
	}
}

定义解析类

package com.wyl.example;


import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;
//使用SAX方式解析xml类
public class SAXPersonService {
	public static List<Person> readXml(InputStream inStream) throws ParserConfigurationException, SAXException, IOException{
		//得到SAX哭器的工厂对象
		SAXParserFactory spf = SAXParserFactory.newInstance();
		//让工厂对象去创建器对象
		SAXParser saxParser = spf.newSAXParser();
		//创建DefaultHandler对象
		XMLContentHandler handler = new XMLContentHandler();
		//使用parserr 的parser(inputstream in,DefaultHanderHandler handler);
		saxParser.parse(inStream, handler);
		//关闭字节流
		inStream.close();
		return handler.getPersons();
	}
}

package com.wyl.example;

import java.util.ArrayList;
import java.util.List;

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

import android.util.Log;
//定义SAX解析器的解析handle对象
public class XMLContentHandler extends DefaultHandler {

	public static final String TAG = "XMLContentHandler";
	//定义结果链表
	private List<Person> persons;
	private Person person;
	//记录当前的节点名称
	private String preTag;

	public List<Person> getPersons() {
		return persons;
	}

	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub
		super.startDocument();
		//初始化结果链表
		persons = new ArrayList<Person>();
		Log.i(TAG, "开始解析...");
	}

	//uri 命名空间 localName:不带命名空间前缀的标签名 qName:带命名空间前缀的标签名 attributes:属性集合
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// TODO Auto-generated method stub
		super.startElement(uri, localName, qName, attributes);
		//解析名称为person的节点
		if ("person".equals(localName)) {
			//初始化节点person对象
			person = new Person();
			//得到并设置id属性
			person.setId(new Integer(attributes.getValue("id")));
		}
		//记录当前节点名称
		preTag = localName;
		Log.i(TAG, "解析元素:" + localName);
	}

	//ch[]内容 start 其实位置 length 长度
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// TODO Auto-generated method stub
		super.characters(ch, start, length);
		if (person != null) {
			//解析字段内容
			String data = new String(ch, start, length);
			//设置相应的属性
			if ("name".equals(preTag)) {
				person.setName(data);
			} else if ("age".equals(preTag)) {
				person.setAge(new Short(data));
			}
		}
		Log.i(TAG, "解析的内容:" + new String(ch, start, length));
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		// TODO Auto-generated method stub
		super.endElement(uri, localName, qName);
		//person结束的节点
		if ("person".equals(localName) && person != null) {
			//添加person到结果list中
			persons.add(person);
			person = null;
		}
		preTag = null;
		Log.i(TAG, localName + "解析完毕");
	}

	@Override
	public void endDocument() throws SAXException {
		// 文档解析完毕
		super.endDocument();
		Log.i(TAG, "文档解析完毕");
	}
}

SAX解析xml文件特点是逐行进行加载,逐行解析,可以中途进行停止解析。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值