Android解析本地XML文件(PULL)之省-市-区三级目录

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();//所有元素解析完成进行打印工作
    }

以上内容都是作者辛苦自己码出来的,如有不对的地方欢迎大家指正,如果转载请注明出处,谢谢!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值