Android中XML解析-SAX解析

昨天由于时间比较匆忙只写了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一般来说需要重写的方法有四个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//用于处理文档解析开始事件
 
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: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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;
    }
 
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
 
    }
 
    public BookHandler() {
        super();
        bookList = new ArrayList<Book>();
    }
 
    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
    }
 
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // 读取Book
        tagName = localName;
        if (localName.equals("Book")) {
            book = new Book();
            book.setName(attributes.getValue("name"));
        }
    }
 
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        if (localName.equals("Book")) {
            bookList.add(book);
        }
    }
 
    @Override
    public 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中的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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>
   根据最高人民检察院授权,军事检察院对*军委原副主席徐才厚以涉嫌受贿犯罪立案侦查。20141027日,对该案侦查终结,移送审查起诉。
        </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文件中的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public  List<Book>  getBooksBySAX(String fileName){
    //实例一个SAX工厂
    SAXParserFactory factory = SAXParserFactory.newInstance();
    try {
        //实例一个解析器对象
        SAXParser parser = factory.newSAXParser();
        //实例化一个XML解析流
        XMLReader reader = parser.getXMLReader();
        //自定义的Handler
        BookHandler 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 block
        e.printStackTrace();
    catch (SAXException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return list;
}

Activity中的调用:

1
2
3
4
5
        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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class saxAdapter extends BaseAdapter {
 
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return list.size();
    }
 
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return null;
    }
 
    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return 0;
    }
 
    @Override
    public 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。

本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4069137.html,如需转载请自行联系原作者

上一篇:oracle asm 拷贝数据库到本地磁盘


下一篇:mysql update 四种情况