昨天由于时间比较匆忙只写了Android中的XML解析的Dom方式,这种方式比较方便,很容易理解,最大的不足就是内容多的时候,会消耗内存。SAX(Simple API for XML)是一个解析速度快并且占用内存少的xml解析器,非常适合用于Android等移动设备。这次使用SAX解析XML文件接着我们来看看另一种解析xml的方式,通过sax来对xml文档进行解析。

自定义Handler

SAX解析XML文件采用的是事件驱动,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件。所谓事件,实就是一些回调(callback)方法,这些方法(事件)定义在ContentHandler接口。Android中Default已经封装了这些方法,继承DefaultHandler一般来说需要重写的方法有四个:

//用于处理文档解析开始事件public void startDocument()throws SAXException//处理元素开始事件,从参数中可以获得元素所在名称空间的uri,元素名称,属性类表等信息public void startElement(String namespacesURI , String localName , String qName , Attributes atts) throws SAXException//处理元素结束事件,从参数中可以获得元素所在名称空间的uri,元素名称等信息public void endElement(String namespacesURI , String localName , String qName) throws SAXException//处理元素的字符内容,从参数中可以获得内容public void characters(char[] ch , int start , int length)  throws SAXException

自定义的BookHandler: 

public class BookHandler extends DefaultHandler {private static List<Book> bookList = null;private static String tagName;private Book book = null;public List<Book> getBooks() {return bookList;}@Overridepublic void startDocument() throws SAXException {// TODO Auto-generated method stubsuper.startDocument();}public BookHandler() {super();bookList = new ArrayList<Book>();}@Overridepublic void endDocument() throws SAXException {// TODO Auto-generated method stubsuper.endDocument();}@Overridepublic void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {// 读取BooktagName = localName;if (localName.equals("Book")) {book = new Book();book.setName(attributes.getValue("name"));}}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {if (localName.equals("Book")) {bookList.add(book);}}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {String value = new String(ch, start, length).trim();  if(value != null && !"".equals(value) && !"\n".equals(value)) {switch (tagName) {case "Title":Log.i("titleString", value);book.setTitle(value);}}}}

 Demo实现

看下效果图,跟上次一样:

Android中XML解析-SAX解析

Book.xml中的内容:

<?xml version="1.0" encoding="utf-8"?><Books>    <Book name="康师傅的亿万帝国" >        <Title>    据周元根的小学同学回忆,大约7岁那年,周元根开始读小学,由于和别人重名,于是改了名字。但他在村里一直沿用“周元根”这个名字,周家祖坟的5块墓碑上,刻的也是“周元根”这个名字。        </Title>        <Picture>     http://p.qpic.cn/ninja/0/ninja1406636943/0        </Picture>    </Book>    <Book name="徐才厚受贿额特别巨大" >        <Title>   根据最高人民检察院授权,军事检察院对中央军委原副主席徐才厚以涉嫌受贿犯罪立案侦查。2014年10月27日,对该案侦查终结,移送审查起诉。        </Title>        <Picture>http://www.sinaimg.cn/dy/slidenews/1_img/2014_44/2841_506865_709392.jpg        </Picture>    </Book>    <Book name="发改委副司长魏鹏远" >        <Title>    最高人民检察院反贪污贿赂总局局长徐进辉今日表示,煤炭司副司长魏鹏远家中搜查发现现金折合人民币2亿余元,成为建国以来检察机关一次起获赃款现金数额最大的案件。        </Title>        <Picture>    http://img1.cache.netease.com/catchpic/D/DC/DCB2315FD0F50C665BB1474768192642.jpg        </Picture>    </Book></Books>

获取XML文件中的内容:

public  List<Book>  getBooksBySAX(String fileName){//实例一个SAX工厂SAXParserFactory factory = SAXParserFactory.newInstance();try {//实例一个解析器对象SAXParser parser = factory.newSAXParser();//实例化一个XML解析流XMLReader reader = parser.getXMLReader();//自定义的HandlerBookHandler bookHandler=new BookHandler();reader.setContentHandler(bookHandler);reader.parse( new InputSource(this.getResources().getAssets().open("Book.xml")));list=bookHandler.getBooks();} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return list;}

Activity中的调用:

                list=getBooksBySAX("Book.xml");Log.i("test",String.valueOf(list.size()));View view = getLayoutInflater().inflate(R.layout.activity_book_sax, null);ListView listView = (ListView) findViewById(R.id.list_sax);listView.setAdapter(new saxAdapter());

 自定义的Adapter:

class saxAdapter extends BaseAdapter {@Overridepublic int getCount() {// TODO Auto-generated method stubreturn list.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Book book = (Book) list.get(position);View view = null;if (convertView == null) {LayoutInflater layoutInflater = getLayoutInflater();view = layoutInflater.inflate(R.layout.book, null);} else {view = convertView;};TextView titleView = (TextView) view.findViewById(R.id.itemTitle);titleView.setText(book.getName());TextView contentView = (TextView) view.findViewById(R.id.itemText);contentView.setText(book.getTitle());return view;}}

  这里面最重要的就是自定义Handler,里面需要注意的是startElement,endElement,characters执行顺序的问题,顺序是startElement=>characters=>endElement,先解析标签,直到找到内容之后才开始endElement。

更多相关文章

  1. Android事件总线(三)otto用法全解析
  2. 无废话Android之常见adb指令、电话拨号器、点击事件的4种写法、
  3. Android事件分发机制浅析
  4. 更简单的学习Android事件分发
  5. android 移除remove元素
  6. 【笔记】android捕获触摸事件
  7. android 同一个TextView不同文字的点击事件
  8. Android事件传递机制
  9. Android studio实现按钮的点击事件

随机推荐

  1. Android(安卓)Cursor
  2. android 震动
  3. Android 动态设置控件高度
  4. android CTS测试使用方法
  5. Android菜鸟笔记-获取设备信息
  6. 让Android studio支持java8
  7. Android 图片资源的异步加载2
  8. android 常用调用系统功能
  9. Android源码去除状态栏
  10. android http中请求访问添加 cookie