俩种XML解析SAX解析和Pull解析

SAX是基于事件流,而DOM是基于文档树结构。


 DOM原理:先将文件读取进入一个驻入内存的树结构。因为在内存,便于操作和管理,但是浪费资源和时间。

 SAX原理: 基于事件,这个表示读取到xml的结点会根据结点名称来读取相应的数据,占用资源少。但是无状态,非持久,如果数据没保存就没了。


DOM4J:很好很强大。

JDOM:就是对SAX的封装。适合简单的创建和解析。


 今天使用的例子就是安卓使用的SAX和安卓自带的Pull解析。

先看看实验citys.xml

<?xml version="1.0" encoding= "UTF-8"?>
<citys>
       <city id= "23">
             <name>nice</name>
             <number>30</ age>
       </city>
      
       <city id="20">
             <name>work</name>
             <number>23</ age>
       </city>
</citys>

第一种解析方式SAX



/**
	 * SAX解析
	 */
	@Override
	public List<City> parseXmlBySax(InputStream iis) throws Exception {
		List<City> list = new ArrayList<City>();
		SAXParserFactory spf = SAXParserFactory.newInstance();
		SAXParser parser = spf.newSAXParser(); // 通过工厂获得解析器

		CityContextHandler handler = new CityContextHandler();
		parser.parse(iis, handler); // 传一个流和处理器 这样体现了一种思想 有点像适配器 需要什么就写什么
		iis.close(); // 小细节 关闭流
		list = handler.getList();
		return list;
	}


import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * 处理器需要基础DefaultHandler
 * 重写startDocument()   startElement()  endElement()   characters()  
 * 最好是根据xml新建一个JavaBean   操作方便  
 * 
 * @author suibian
 *
 */
public class CityContextHandler extends DefaultHandler {
	private List<City> list=null;
	private City city=null;
	private String targetname=null;
	
	public List<City> getList() {
		return list;
	}

	/**
	 * 开始就初始化集合 
	 */
	@Override
	public void startDocument() throws SAXException {
		list=new ArrayList<City>();
	}

	/**
	 * 元素开头要判断
	 * 如果是city则初始化
	 * 		 name则set
	 * 		 location则set
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if(localName.equals("citys")){   //这一句我自己加上去的
			return;
		}
		 if(localName.equals("city")){
			 this.city=new City();
			 city.setId(Integer.valueOf(attributes.getValue("id")));
		 }
		 this.targetname=localName;
	}
	
	/**元素结尾
	 * 如果是city则加入集合中  设置city=null
	 */
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		 if(localName.equals("city")){
			 list.add(city);
			 city=null;
		 }
		 this.targetname=null;
	}
	
	/**
	 * 给JavaBean注参处理
	 */
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		String data=new String(ch,start,length);
		 if(this.targetname!=null&&(!(data.equals("")))){
			 if(this.targetname.equals("name")){
				 this.city.setName(data);
			 }else{
				 this.city.setNumber(data);
			 }
		 }
	}
}


第二种Pull解析

/**
	 * Pull解析
	 * 错误:这玩意非得在线程中才能得到正确的结果
	 * 在流中解析,是边解析边连接 
	 */
	@Override
	public  List<City> parseXmlByPull(InputStream iis) throws Exception {
		List<City> list = null;
		City city = null;
		XmlPullParser pull = XmlPullParserFactory.newInstance().newPullParser();
		pull.setInput(iis, "UTF-8");
		int event = pull.getEventType();
		while (event != XmlPullParser.END_DOCUMENT) {
			switch (event) {
			case XmlPullParser.START_DOCUMENT:
				list = new ArrayList<City>();
				break;
			case XmlPullParser.START_TAG:
				if (pull.getName().equals("city")) {
					city = new City();
					city.setId(Integer.valueOf(pull.getAttributeValue(0)));
				}
				if (pull.getName().equals("name")) {
					city.setName(pull.nextText());
				}

				if (pull.getName().equals("number")) {
					city.setNumber(pull.nextText());
				}
				break;
			case XmlPullParser.END_TAG:
				if (pull.getName().equals("city")) {
					list.add(city);
					city = null;
				}
				break;
			}
			event = pull.next();
		}
		return list;
	}

这个困惑了我好久,出现了错误为什么setup() must be ....... @1 null 什么的 不记得了,这个是提示测试的时候是要放在一个线程中才能解析的,后来在https://github.com/blog 才找到的答案,庆幸英语水平还勉强看得懂。  

关于DOM解析什么的就不多说了,总之想说的是,这个只是工具,拿来用就是了,至于原理懂了行。  


我是菜鸟,我在路上。 

2015年5月17日23:48:20


你可能感兴趣的:(xml,android,sax,pull)