昨天由于时间比较匆忙只写了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实现
看下效果图,跟上次一样:
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>
根据最高人民检察院授权,军事检察院对中央军委原副主席徐才厚以涉嫌受贿犯罪立案侦查。
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文件中的内容:
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,如需转载请自行联系原作者