解析XML通常有3种方法:
1)SAX:SAX解析器的优点是解析速度快,占用内存少。
2)DOM:对于特别大的文档,解析和加载整个文档将会很耗资源。
3)PULL:PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器。
这里只介绍PULL解析方法的使用。步骤如下:
1、在项目的assets目录中放置一个XML文档provinceandcity.xml,内容如下:
<resources>
<province id="1" name="直辖市">
<item>
<id>1</id>
<name>北京</name>
</item>
<item>
<id>2</id>
<name>上海</name>
</item>
<item>
<id>3</id>
<name>天津</name>
</item>
<item>
<id>4</id>
<name>重庆</name>
</item>
</province>
<province id="2" name="广东">
<item>
<id>5</id>
<name>广州</name>
</item>
<item>
<id>6</id>
<name>深圳</name>
</item>
<item>
<id>7</id>
<name>珠海</name>
</item>
<item>
<id>8</id>
<name>汕头</name>
</item>
<item>
<id>9</id>
<name>韶关</name>
</item>
<item>
<id>10</id>
<name>佛山</name>
</item>
<item>
<id>11</id>
<name>江门</name>
</item>
<item>
<id>12</id>
<name>湛江</name>
</item>
<item>
<id>13</id>
<name>茂名</name>
</item>
<item>
<id>14</id>
<name>肇庆</name>
</item>
<item>
<id>15</id>
<name>惠州</name>
</item>
<item>
<id>16</id>
<name>梅州</name>
</item>
<item>
<id>17</id>
<name>汕尾</name>
</item>
<item>
<id>18</id>
<name>河源</name>
</item>
<item>
<id>19</id>
<name>阳江</name>
</item>
<item>
<id>20</id>
<name>清远</name>
</item>
<item>
<id>21</id>
<name>东莞</name>
</item>
<item>
<id>22</id>
<name>中山</name>
</item>
<item>
<id>23</id>
<name>潮州</name>
</item>
<item>
<id>24</id>
<name>揭阳</name>
</item>
<item>
<id>25</id>
<name>云浮</name>
</item>
</province>
........
</resources>
2)创建一个City类,用于暂存xml中的数据,看一下City.java的代码:
package com.example.provinceandcityforcn;
public class City {
int cityId;
int provinceId;
String cityName;
String provinceName;
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
public int getProvinceId() {
return provinceId;
}
public void setProvinceId(int provinceId) {
this.provinceId = provinceId;
}
public String getProvinceName() {
return provinceName;
}
public void setProvinceName(String provinceName) {
this.provinceName = provinceName;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
}
3)PULL解析xml:
package com.example.provinceandcityforcn;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.content.res.XmlResourceParser;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
/**
* 解析XML,获取城市
*
*/
public class CityPullParse {
public static ArrayList<City> Parse(String CityString){
ArrayList<City> CityArray = new ArrayList<City>();
try {
//定义工厂 XmlPullParserFactory
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//定义解析器 XmlPullParser
XmlPullParser parser = factory.newPullParser();
//获取xml输入数据
parser.setInput(new StringReader(CityString));
CityArray = ParseXml(parser);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return CityArray;
}
public static ArrayList<City> Parse(InputStream cityIS){
ArrayList<City> cityArray = new ArrayList<City>();
try {
//定义工厂 XmlPullParserFactory
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//定义解析器 XmlPullParser(要转换为XmlResourceParser,否则不能正常解析)
XmlResourceParser parser =(XmlResourceParser) factory.newPullParser();
//获取xml输入数据
parser.setInput(cityIS,"utf-8");
cityArray = ParseXml(parser);
} catch (XmlPullParserException e) {
e.printStackTrace();
}
return cityArray;
}
/**
* @param parser
* @return
*/
public static ArrayList<City> ParseXml(XmlPullParser parser){
ArrayList<City> CityArray = new ArrayList<City>();
City CityTemp = null;
int provinceId = 0;
int cityId;
String cityName;
String provinceName = "";
try {
//开始解析事件
int eventType = parser.getEventType();
//处理事件,不碰到文档结束就一直处理
while (eventType != XmlPullParser.END_DOCUMENT) {
//因为定义了一堆静态常量,所以这里可以用switch
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
//给当前标签起个名字
String tagName = parser.getName();
if(tagName.equals("province")){
provinceId = Integer.parseInt(parser.getAttributeValue(null, "id"));//获取province节点属性为id的值
//provinceId = Integer.parseInt(parser.getAttributeValue(0));//第二种方式(获取province节点属性为id的值
provinceName = String.valueOf(parser.getAttributeValue(null, "name"));//获取province节点属性为name的值
}else if(tagName.equals("item")){
CityTemp = new City();
}else if(tagName.equals("id")){
cityId = Integer.parseInt(parser.nextText());
parser.next();
cityName = parser.nextText();
CityTemp.setProvinceId(provinceId);
CityTemp.setCityId(cityId);
CityTemp.setProvinceName(provinceName);
CityTemp.setCityName(cityName);
CityArray.add(CityTemp);
}
break;
case XmlPullParser.END_TAG:
break;
case XmlPullParser.END_DOCUMENT:
break;
}
//别忘了用next方法处理下一个事件,忘了的结果就成死循环#_#
eventType = parser.next();
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return CityArray;
}
}
4)UI调用:
(1)布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".CityActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="50dip"
android:gravity="center"
android:orientation="horizontal"
android:padding="5dip" >
<Button
android:id="@+id/btn_getcity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取城市列表" >
</Button>
</LinearLayout>
<ScrollView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" >
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="" >
</TextView>
</ScrollView>
</LinearLayout>
(2)代码文件
package com.example.provinceandcityforcn;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.app.Activity;
import android.content.res.XmlResourceParser;
public class CityActivity extends Activity implements OnClickListener {
private ArrayList<City> cityArray;
private String cityStr;
private TextView textview;
private String fileName = "provinceandcity.xml";
private XmlResourceParser provinceandcityParser;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_city);
((Button)findViewById(R.id.btn_getcity)).setOnClickListener(this);
textview=(TextView)findViewById(R.id.textview);
}
private void getcity(){
provinceandcityParser = getXMLFromResXml(fileName);
cityArray =CityPullParse.ParseXml(provinceandcityParser);
//cityArray = CityPullParse.Parse(getInputStreamFromAssets(fileName));
for(City city : cityArray){
cityStr += "省份ID["+city.getProvinceId() + "],省份name["+city.getProvinceName() + "],城市ID[" + city.getCityId() +"], "+city.getCityName()+"\n";
}
textview.setText(cityStr);
}
public XmlResourceParser getXMLFromResXml(String fileName){
XmlResourceParser xmlParser = null;
try {
xmlParser = this.getResources().getXml(R.xml.provinceandcity);
return xmlParser;
} catch (Exception e) {
e.printStackTrace();
}
return xmlParser;
}
/**
* 从assets中读取文件到InputStream中
*/
public InputStream getInputStreamFromAssets(String fileName){
try {
InputStream inputStream = getResources().getAssets().open(fileName);
return inputStream;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v.getId()==R.id.btn_getcity){
getcity();
}
}
}
5)运行结果: