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个接口的连接。
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文件特点是逐行进行加载,逐行解析,可以中途进行停止解析。