Android解析本地XML文件(PULL)之省-市-区三级目录
PULL解析器运行方式与sax解析器很相似,它提供了类似的事件。如开始元素和结束元素,使用parse.next()可以进行下一个元素并且出发相应的时间,时间将作为代码被发送,因此可以使用一个switch来对时间进行选择,然后进行相应的处理,。当开始解析元素的时候,调用parser.nextText()法官法可以获得下一个Text类型的元素。
- PULL Parser用一个顺序的时间和标记序列来呈现文档的元素(也就是说PULL Parser是通过顺序来读取XML文件中的数据的)
- 通过调用getEventType来确定当前的读取事件
- 文档读取都是从START_DOCUMENT事件开始,到END_DOCUMENT事件结束
- 遍历标记,只需要调用next即可遍历下一个标记
- 调用getName可以提取每个标记的名称
- 调用getNextText可以提取每组标记之间的文本信息
xml解析文件
我们需要解析的文件如下这里仅仅截取了部分代码粘贴上来,如下所示包含了省-市-区且该xml文件中的标记有诸多重复的地方这里采用了栈结构来存储结点:
<data>
<item id='0'>
<id>110000</id>
<name>北京</name>
<city>
<item id='0'>
<id>110100</id>
<name>北京市</name>
<district>
<item id='0'>
<id>110101</id>
<name>东城区</name>
</item>
<item id='1'>
<id>110102</id>
<name>西城区</name>
</item>
<item id='2'>
<id>110105</id>
<name>朝阳区</name>
</item>
<item id='3'>
<id>110106</id>
<name>丰台区</name>
</item>
<item id='4'>
<id>110107</id>
<name>石景山区</name>
</item>
<item id='5'>
<id>110108</id>
<name>海淀区</name>
</item>
<item id='6'>
<id>110109</id>
<name>门头沟区</name>
</item>
<item id='7'>
<id>110111</id>
<name>房山区</name>
</item>
<item id='8'>
<id>110112</id>
<name>通州区</name>
</item>
<item id='9'>
<id>110113</id>
<name>顺义区</name>
</item>
<item id='10'>
<id>110114</id>
<name>昌平区</name>
</item>
<item id='11'>
<id>110115</id>
<name>大兴区</name>
</item>
<item id='12'>
<id>110116</id>
<name>怀柔区</name>
</item>
<item id='13'>
<id>110117</id>
<name>平谷区</name>
</item>
<item id='14'>
<id>110228</id>
<name>密云区</name>
</item>
<item id='15'>
<id>110229</id>
<name>延庆区</name>
</item>
</district>
</item>
</city>
</item>
</data>
代码示例
xml文件解析方式如下:
首先创建省得存储类:这里需要保存省得相关信息有名称、ID、以及该省下的所有的市的信息。
public class provinces {
//保存省名称
private String Provinces;
//保存省ID
private String Provinces_id;
//保存省下面的所有市
private List<citys> Provinces_city;
public provinces() {
}
public provinces(String provinces, String provinces_id, List<citys> provinces_city) {
Provinces = provinces;
Provinces_id = provinces_id;
Provinces_city = provinces_city;
}
public String getProvinces() {
return Provinces;
}
public void setProvinces(String provinces) {
Provinces = provinces;
}
public String getProvinces_id() {
return Provinces_id;
}
public void setProvinces_id(String provinces_id) {
Provinces_id = provinces_id;
}
public List<citys> getProvinces_city() {
return Provinces_city;
}
public void setProvinces_city(List<citys> provinces_city) {
Provinces_city = provinces_city;
}
}
省完了,就该是市的信息了,这里同样我们需要市的名称、ID、该城市下所有的区的信息:
public class citys {
//保存市的名称
private String citys;
//保存市的ID
private String citys_id;
//保存市下面的所有的区
private List<areas> citys_areas;
public citys() {
}
public citys(String citys, String citys_id, List<areas> citys_areas) {
this.citys = citys;
this.citys_id = citys_id;
this.citys_areas = citys_areas;
}
public String getCitys() {
return citys;
}
public void setCitys(String citys) {
this.citys = citys;
}
public String getCitys_id() {
return citys_id;
}
public void setCitys_id(String citys_id) {
this.citys_id = citys_id;
}
public List<areas> getCitys_areas() {
return citys_areas;
}
public void setCitys_areas(List<areas> citys_areas) {
this.citys_areas = citys_areas;
}
}
最后是区的相关信息,由于区是最后一级只包含了区名称与区ID:
public class areas {
private String areas;
private String areas_id;
public areas() {
}
public areas(String areas_id, String areas) {
this.areas_id = areas_id;
this.areas = areas;
}
public String getAreas() {
return areas;
}
public void setAreas(String areas) {
this.areas = areas;
}
public String getAreas_id() {
return areas_id;
}
public void setAreas_id(String areas_id) {
this.areas_id = areas_id;
}
}
接下来我们开始解析xml文件了,这里我把省市区的xml文件放在了本地的assets目录下,相关的代码说明在代码里面有详细的注释,如果不懂的话可以私信我:
private void parseXMLWithPull(StringBuilder stringBuilder) {
try {
//获取XMLPull的解析对象
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
//将字节流传送到解析器中
xmlPullParser.setInput(new StringReader(stringBuilder.toString()));
//记录下当前的读取事件
int eventType = xmlPullParser.getEventType();
//用来临时记录id和name
String id = "";
String name = "";
//循环读取文档
while (eventType != XmlPullParser.END_DOCUMENT) {
//nodeName记录下当前读取的节点的名称
String nodeName = xmlPullParser.getName();
switch (eventType) {
//根据读取事件来判断执行的操作
case XmlPullParser.START_DOCUMENT://开始文档事件
//初始化栈,用来存放读取到的节点的名称,因为该文件中的名称跟id的节点名称是重复的
//所以笔者想到了这种办法来控制判断目前读取的是哪一个类型的id和name,当然也有其他方法,读者可以自行试试
stack = new Stack();
break;
case XmlPullParser.START_TAG://开始元素事件,凡是读取到的是开始节点,该节点名称就入栈
if ("root".equals(nodeName)) {//取得节点名称并判断
stack.push(nodeName);
Log.e("pullActivity", nodeName + "入栈");
} else if ("data".equals(nodeName)) {
stack.push(nodeName);
Log.e("pullActivity", nodeName + "入栈");
} else if ("item".equals(nodeName)) {
stack.push(nodeName);
Log.e("pullActivity", nodeName + "入栈");
if (stack.size() == 7) {//通过栈内存放的节点数量来判断目前处于哪一个节点位置
dis_bean = new areas();
}if (stack.size() == 5) {
citys_bean = new citys();
} if (stack.size() ==3){
province_bean = new provinces();
Log.e("pullActivity", "创建province_bean");
}
} else if ("id".equals(nodeName)) {
id = xmlPullParser.nextText();
if (stack.size() == 7) {
dis_bean.setAreas_id(id);
}else if (stack.size()==5){
citys_bean.setCitys_id(id);
}else if (stack.size()==3){
province_bean.setProvinces_id(id);
}
} else if ("name".equals(nodeName)) {
name = xmlPullParser.nextText();
if (stack.size() == 7) {
dis_bean.setAreas(name);
}else if (stack.size()==5){
citys_bean.setCitys(name);
}else if (stack.size() ==3){
province_bean.setProvinces(name);
}
} else if ("city".equals(nodeName)) {
stack.push(nodeName);
Log.e("pullActivity", nodeName + "入栈");
CitysList = new ArrayList<>();
} else if ("district".equals(nodeName)) {
stack.push(nodeName);
Log.e("pullActivity", nodeName + "入栈");
DistrictList = new ArrayList<>();
}
break;
case XmlPullParser.END_TAG://结束元素事件,凡是读取到结束节点则对应的开始元素节点出栈
Log.e("pullActivity", nodeName + "出栈");
if ("district".equals(nodeName)) {
stack.pop();
citys_bean.setCitys_areas(DistrictList);
} else if ("item".equals(nodeName)) {
stack.pop();
if (stack.size() == 6) {
DistrictList.add(dis_bean);
} else if (stack.size() == 4) {
CitysList.add(citys_bean);
} else if (stack.size() ==2){
Log.e("pullActivity", "Lists放入");
Lists.add(province_bean);
}
}else if ("city".equals(nodeName)){
stack.pop();
province_bean.setProvinces_city(CitysList);
}else if ("data".equals(nodeName)){
stack.pop();
Log.e("pullActivity", "Lists大小:"+Lists.size());
Log.e("pullActivity", "数据解析完成");
}else if ("root".equals(nodeName)){
stack.clear();
}
break;
default:
break;
}
eventType = xmlPullParser.next();//进入下一个元素并触发相应事件
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
print();//所有元素解析完成进行打印工作
}
以上内容都是作者辛苦自己码出来的,如有不对的地方欢迎大家指正,如果转载请注明出处,谢谢!