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; } }