SAX解析XML

一、书本内容
1、SAX介绍
SAX(Simple API for XML)是基于事件驱动的,边下载边解析。当然Android的事件机制是基于回调函数的,在用SAX解析XML文档的时候,在读取到文档开始和结束标签时候就会回调一个事件,在读取到其他节点与内容的时候也会回调一个事件。
既然涉及事件,就有事件源和事件处理器。在SAX接口中,事件源是org.xml.sax包中的XMLReader,它通过parser()方法来解析XML文档,并产生事件。事件处理器是org.xml.sax包中的ContentHandler、DTDHandler、ErrorHandler,以及EntityResolver这4个接口。
XMLReader通过相应事件处理器注册方法setXXX()来完成与ContentHandler、DTDHandler、ErrorHandler,以及EntityResolver这4个接口的连接。


XMLReader接口中一些重要方法
(1)
处理器名称:ContentHandler
处理事件:跟文档内容有关的事件:文档的开始与结束、XML元素的开始与结束、可忽略的实体、名称空间前缀映射开始和结束、处理指令、字符数据和可忽略的空格等。
XMLReader注册方法:setContentHandler(ContentHandler h)
(2)
处理器名称:ErrorHandler
处理事件:处理XML文档时产生的错误
XMLReader注册方法:setErrorHandler(ErrorHandler h)
(3)
处理器名称:DTDHandler
处理事件:处理对文档的DTD进行解析时产生的相应事件
XMLReader注册方法:setDTDHandler(DTDHandler h)
(3)
处理器名称:EntityResolver
处理事件:处理外部实体
XMLReader注册方法:setEntityResolver(EntityResolver r)


程序员定义的事件处理类在实现该接口时,必须实现接口中的所有4个方法。为了减少程序员的工作量,SDK提供了DefaultHandler类来做事件处理。


DefaultHandler类的一些主要事件的回调方法
(1)
方法:setDocumentLocator(Locator locator)
含义:设置一个可以定位文档位置的对象
(2)
方法:startDocument()
含义:用于处理文档解析事件开始事件
(3)
方法:startElement(String uri, String localName, String qName,Attributes attributes)
含义:处理元素开始事件,从参数中可以获取元素所在的URL、元素名称、属性列表等信息
(4)
方法:characters(char[] ch, int start, int length)
含义:处理元素的字符内容,从参数中可以获得内容
(5)
方法:endElement(String uri, String localName, String qName)
含义:处理元素结束事件,参数中可以获得元素所在URL、元素名称等
(6)
方法:endDocument()
含义:用于处理文档解析的结束事件


2、SAX解析XML步骤
可以通过XMLReader及DefaultHandler的配合来解析XML。基本思路如下:
(1)创建SAXParserFactory对象;
SAXParserFactory factory=SAXParserFactory.newInstance();
(2)根据SAXParserFactory.newSAXParser()方法返回一个SAXPaser解析器;
SAXPaser parser=factory.newSAXParser();
(3)根据SAXParser解析器获取事件源对象XMLReader;
XMLReader xmlReader=parser.getXMLReader();
(4)实例化一个DefaultHandler对象;
SAXParserHelper helperHandler=new SAXParserHelper();
(5)连接事件源对象XMLReader到事件处理类DefaultHandler中;
xmlReader.setContentHandler(helperHandler);
(6)调用XMLReader的parse方法从输入源中获取的XML数据;
InputStream stream=getResources().getAssets().open("link.xml");
InputSource is=new InputSource(stream);
xmlReader.parse(is);
(7)通过DefaultHandler返回需要的数据集合。
helperHandler.getLinks();






二、自己项目
1、解析步骤
(1)加载需要解析的文件
InputStream inputStream=MainActivity.class.getClassLoader().getResourceAsStream("Persons.xml");
(2)创建一个SAXParser类
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
(3)创建自己的解析类
MySaxParser mySaxPaser=new MySaxParser();
(4)解析XML文件数据
saxParser.parse(inputStream,mySaxPaser);
(5)通过DefaultHandler返回需要的数据集合
ArrayList<Person> persons=mySaxPaser.getList();


2、项目代码
//MainActivity.java
InputStream inputStream=MainActivity.class.getClassLoader().getResourceAsStream("Persons.xml");
SAXParser saxParser;
try 
{
	saxParser = SAXParserFactory.newInstance().newSAXParser();//SAXParser解析器
	MySaxParser mySaxPaser=new MySaxParser();//新建事件处理器
	saxParser.parse(inputStream,mySaxPaser);
	ArrayList<Person> persons=mySaxPaser.getList();
	for(int i=0;i<persons.size();i++)
	{
		Person person=persons.get(i);
		tv_parse.append("\nid="+person.getId()+";age="+person.getAge()+";name="+person.getName());
	}
} 
catch (ParserConfigurationException e) 
{
	e.printStackTrace();
} 
catch (SAXException e) 
{
	e.printStackTrace();
}
catch (IOException e) 
{
	e.printStackTrace();
}








//MySaxParser.java
public class MySaxParser extends DefaultHandler 
{
	Person person;
	ArrayList<Person> persons;
	String element;
	static final String TAG="mySax";
	
	@Override
	public void startDocument() throws SAXException 
	{
		persons=new ArrayList<Person>();
		Log.i(TAG,"now begin to parse document");
	}
	
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		element=localName;
		if(element.equals("Person"))
		{
			person=new Person();
			String id=attributes.getValue(0);
			person.setId(id);
		}
		Log.i(TAG, "now begin to parse the element value:"+element);
	}
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException 
	{
		String s=new String(ch,start,length).trim();
		if(!s.equals(""))
		{
			if(element.equals("name"))
			{
				person .setName(s);
			}
			else if(element.equals("age"))
			{
				person .setAge(s);
			}
			Log.i(TAG, "now parse the element value:"+s);
		}
	}
	
	
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		element=localName;
		if(element.equals("Person"))
		{
			persons.add(person);
			person=null;
		}
		Log.i(TAG, "now end the element value:"+localName);
	}
	
	@Override
	public void endDocument() throws SAXException 
	{
		Log.i(TAG,"now end the document");
	}


	public ArrayList<Person> getList() {
		return persons;
	}


}





//Person.java
public class Person 
{
	String id;
	String name;
	String age;
	
	public Person() 
	{
		super();
		id="0";
		name="王二";
		age="50";
	}
	public Person(String id, String name, String age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
	
}




//Person.xml

<Persons>
    <Person id="1">
        <name>张三</name>
        <age>20</age>
    </Person>
    <Person id="2">
        <name>李四</name>
        <age>30</age>
    </Person>
    <Person id="3">
        <name>王五</name>
        <age>30</age>
    </Person>
</Persons>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值