昨天由于时间比较匆忙只写了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实现

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

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]文本框实现搜索和清空效果
  2. 无废话Android之常见adb指令、电话拨号器、点击事件的4种写法、
  3. Android(安卓)Service详解(三) AIDL使用解析
  4. [Android]解决Fragment无法使用android:onClick属性
  5. Android:使用Gson解析复杂的JSON数据
  6. 系出名门Android(10) - HTTP 通信, XML 解析, 通过 Hander 实现
  7. Android事件总线(三)otto用法全解析
  8. Android(安卓)中LayoutInflater(布局加载器)之源码篇
  9. 【自动化测试】Android(安卓)Monkey实践

随机推荐

  1. Android(安卓)UI设计
  2. android中的SVG图像的各个属性意义
  3. T-Mobile G3是华为的android
  4. 从源码看Android常用的数据结构 ( SDK23
  5. 《Android 手机程序设计实用教程》PDF版
  6. Android程序开发初级教程
  7. 解决类似微信聊天界面软键盘和表情框冲突
  8. Android高手进阶教程之----Android 中自
  9. Android初级之路-Android开发环境搭建
  10. Android菜单的使用Menu