XML 常用的三種解析方式:
DOM: 全部加載到記憶體,生成一個樹狀結構,占用記憶體比較大。
SAJ: 采用事件驅動,速度快,效率高,不支援回退。
PULL:也是采用事件驅動,文法簡潔。
步驟:
1. 建立XML 解析器:XmlPullParser parser = Xml.newPullParser();
2. 配置解析器:parser.setInput(is, "utf-8");// 參數為 xml 檔案輸入流 和 編碼方式。
3. 根據事件進行解析。
int type = parser.getEventType();// 得到事件類型
type = parser.next();// 擷取下一個事件
事件類型:
XmlPullParser.END_DOCUMENT 文檔末尾。
XmlPullParser.START_TAG 開始标簽
XmlPullParser.END_TAG 結束标簽
擷取标簽名字:parser.getName()
擷取屬性: String idStr = parser.getAttributeValue(0); // 參數為屬性id。
擷取标簽内容:String temp = parser.nextText();
代碼執行個體:
代碼結構:

WeathreService.java
package com.serviatech.weather.service;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import android.util.Xml;
import com.serviatech.weather.domain.WeatherInfo;
public class WeatherService {
public static List<WeatherInfo> getWeatherInfos(InputStream is)
throws Exception {
List<WeatherInfo> weatherInfos = null;
WeatherInfo weatherInfo = null;
XmlPullParser parser = Xml.newPullParser();
parser.setInput(is, "utf-8");// 初始化解析器
int type = parser.getEventType();// 得到事件類型
while (type != XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_TAG:
if ("infos".equals(parser.getName())) {
weatherInfos = new ArrayList<WeatherInfo>();
} else if ("city".equals(parser.getName())) {
weatherInfo = new WeatherInfo();
String idStr = parser.getAttributeValue(0);
weatherInfo.setId(Integer.parseInt(idStr));
} else if ("temp".equals(parser.getName())) {
String temp = parser.nextText();
weatherInfo.setTemp(temp);
} else if ("wind".equals(parser.getName())) {
String wind = parser.nextText();
weatherInfo.setWind(wind);
} else if ("name".equals(parser.getName())) {
String name = parser.nextText();
weatherInfo.setName(name);
}
break;
case XmlPullParser.END_TAG:
if ("city".equals(parser.getName())) {
// 一個城市已經處理完畢
weatherInfos.add(weatherInfo);
weatherInfo = null;// 友善垃圾回收機回
}
break;
}
type = parser.next();
}
return weatherInfos;
}
}
/*
* 解析過程 定義了一個指針,指向開頭
*
* 标簽 tag,文本
*
* 文檔開始 文檔結束
*
* startTag endTag
*/
WeatherInfo.java
package com.serviatech.weather.domain;
public class WeatherInfo {
private int id;
private String name;
private String temp;
private String wind;
public int getId() {
return id;
}
@Override
public String toString() {
return "WeatherInfos [城市id=" + id + ", 名字=" + name + ", 溫度=" + temp
+ ", 風力=" + wind + "]";
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTemp() {
return temp;
}
public void setTemp(String temp) {
this.temp = temp;
}
public String getWind() {
return wind;
}
public void setWind(String wind) {
this.wind = wind;
}
}
/*
* DOM 全部加載到記憶體。生成一個樹狀結構,消耗記憶體比較大
*
* SAX 基于事件的方式,速度快,效率高,不能回退。
*
* PULL 基于事件解析,文法簡潔
*/
MainActivity.java
package com.serviatech.weather;
import java.util.List;
import com.serviatech.weather.domain.WeatherInfo;
import com.serviatech.weather.service.WeatherService;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
try {
List<WeatherInfo> infos = WeatherService
.getWeatherInfos(MainActivity.this.getClassLoader()
.getResourceAsStream("weather.xml"));
StringBuilder sb = new StringBuilder();
for (WeatherInfo info : infos) {
sb.append(info.toString());
sb.append("\n");
}
tv.setText(sb.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(this, "解析資訊失敗", 0).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;
}
}