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 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
原文链接:https://www.f2er.com/xml/296761.html