如果在一个XML文档中我们只需要前面一部分数据,但是使用SAX方式或DOM方式会对整个文档进行解析,尽管XML文档中后面的大部分数据我们其实都不需要解析,因此这样实际上就浪费了处理资源。使用PULL方式正合适。
Pull解析器和SAX解析器虽有区别但也有相似性。他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。
使用pull解析xml文件的基本流程:
* 1. 获取解析器对象XmlPullParser对象parser
* 2. 可以给parser对象设置输入的编码方式
* 3. 循环驱动事件进行解析
* 事件分为4类:
* a. 开始文档:XmlPullParser.START_DOCUMENT值为0
* b. 结束文档:XmlPullParser.END_DOCUMENT值为1
* c. 开始标签:XmlPullParser.START_TAG值为2
* d. 结束标签:XmlPullParser.END_TAG值为3
* 一个事件处理完毕之后,需要提供parser的next方法去驱动下一个事件
books.xml
<books>
<book>
<id>10001</id>
<name>android 01</name>
<price>60.0</price>
<publisher>清华大学出版社</publisher>
</book>
......
<book>
<id>10006</id>
<name>android 06</name>
<price>110.0</price>
<publisher>清华大学出版社</publisher>
</book>
</books>
Books.java
package com.example.analysis_xml;
public class Book {
private int id;
private String name;
private float price;
private String publisher; //出版社
...setter and getter...
public String toString(){
return "\nid="+id+"\nname="+name+"\nprice"+price+"\npublisher="+publisher+"\n";
}
}
BookParser.java
public class BookParser {
public List<Book> bookParser(InputStream is){
List<Book> books = null;
Book book = null;
/*XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parsers = factory.newPullParser();*/
//创建parser解析对象
XmlPullParser parser = Xml.newPullParser();
try {
//获取parser解析的io流
parser.setInput(is,"utf-8");
//获取paser的当前事件类型(START_DOCUMENT = 0;END_DOCUMENT=1;START_TAG=2;END_TAG=3)
int event = parser.getEventType();
while(event != XmlPullParser.END_DOCUMENT){
switch (event) {
case XmlPullParser.START_DOCUMENT:
books = new ArrayList<Book>();
break;
case XmlPullParser.START_TAG:
if("book".equals(parser.getName())){
book = new Book();
}else if("id".equals(parser.getName())){
event = parser.next(); //注意遍历事件的循环变量更新
int id = Integer.parseInt(parser.getText());
book.setId(id);
}
else if("name".equals(parser.getName())){
event = parser.next();
String name = parser.getText();
book.setName(name);
}
else if("price".equals(parser.getName())){
event = parser.next();
float price = Float.parseFloat(parser.getText());
book.setPrice(price);
}else if("publisher".equals(parser.getName())){
event = parser.next();
String publisher = parser.getText();
book.setPublisher(publisher);
}
break;
case XmlPullParser.END_TAG:
//注意判断结束标签中,是否是对象类型,不是就跳过
if("book".equals(parser.getName())){
books.add(book);
book = null;
}
break;
}
event = parser.next(); //循环一次,记得更新遍历循环变量
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return books;
}
}
MainActivity.java
public class MainActivity extends Activity {
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv_show);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_pull:
try {
InputStream is = getAssets().open("books.xml");
List<Book> books = new BookParser().bookParser(is);
for (Book book : books) {
tv.append(book.toString());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
}