首先說這個文章不是原創,最近要用到xml檔案解析,以前都是sax解析的,我到網上聽別人說用android內建的pull方式解析xml檔案要穩定並且有效率。於是我就參考了網上幾個例子,實現了一下,然後把自己認為重要的上去,不重要的就不細說了。
首先就是xml檔案,我就不花哨了,直接複製網上例子的books.xml:
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="12">
<name>thinking in java</name>
<price>85.5</price>
</book>
<book id="15">
<name>Spring in Action</name>
<price>39.0</price>
</book>
</books>
然後就是解析檔案的相關類,這個類裡主要是用到了XmlPullParser類,事實上你真正調用的是KXmlParse這個類。介面我就用普通的InputStream位元組流,因為它比較通用:
public class PullParseService {
public List<Book> parseDateSource(InputStream inputStream) throws Exception{
List<Book> books = null;
Book book = null;
XmlPullParser parse = Xml.newPullParser();
parse.setInput(inputStream, "utf-8");
int event = parse.getEventType();// Returns the type of the current event (START_TAG, END_TAG, TEXT, etc.)
while(event!=XmlPullParser.END_DOCUMENT){
switch (event) {
case XmlPullParser.START_DOCUMENT:
books = new ArrayList<Book>();//初始化books集合
break;
case XmlPullParser.START_TAG:
if(parse.getName().equals("book")){
book = new Book();
//book.setId(Integer.parseInt(parse.getAttributeValue(0)));
//或者這樣也可以的
book.setId(Integer.parseInt(parse.getAttributeValue(null, "id")));
}
if(book!=null){
/**
* note: 這裡的if ...else if.... 不能改為 if。。。 if。。。。(原因是換成後者會出現異常,這個可能與XmlPullParser的getName()的內部實現有聯絡:
* 具體的原因是KXmlParse的nextText()方法本身會調用next()函數具體的看源碼,我也沒有好好看)
*/
if(parse.getName().equals("name")){
book.setName(parse.nextText());
}else if(parse.getName().equals("price")){
book.setPrice(Float.parseFloat(parse.nextText()));
}
}
break;
case XmlPullParser.END_TAG:
if(parse.getName().equals("book")){
books.add(book);
book = null;
}
break;
default:
break;
}
event = parse.next();//進入到下一個元素並觸發相應事件
}
return books;
}
}
在這裡呢還有一點很重要,網上喜歡把xml檔案和類放在一個目錄裡面,感覺這個倒不是採取。這裡我就讓在資源raw檔案裡面。
PullParseService pullParseService = new PullParseService();
try {
/**
* 1.this.getClass().getClassLoader().getResourceAsStream("book.xml");//返回InputSream,如果這樣些,需要把book.xml檔案放在該類檔案的同一個檔案夾
* 2.如果是網路伺服器上的資源,可以這樣:
* String url = "http://eagle.phys.utk.edu/reubendb/UTRoute.php";
* String data = "?lat1=35952967&lon1=-83929158&lat2=35956567&lon2=-83925450";
* String xmlUrl="";
* new URL("").openStream(); // 返回同樣是InputSream
* 3.也就是下面這種,放在資源檔裡面
*/
books = pullParseService.parseDateSource(PullXmlTestActivity.this.getResources().openRawResource(R.raw.books));
} catch (Exception e) {
e.printStackTrace();
}
我發現xml的格式安排跟你的xml檔案的簡潔行也有很大的關係。比如我想儲存一些列點可以的xml檔案如下:
<trkpt lat="35952967" lon="-83929158" grade="1"></trkpt>
然是如果你這樣安排xml的內容,當資料量大的時候,真是讓人無法閱讀。
<trkpt>
<lat>45132123</lat>
<lon>5454</lon>
<grade>5847654</grade>
</trkpt>