Android使用Sax 及Pull 解析Xml demo

客户端开发中,越来越多的接口使用的数据传输类型时json了,xml相对较少。恰好当前要使用到了xml传递数据,写个demo权当记录安卓中如何使用sax 及 pull解析xml.


1.常用的几种解析XML的方式

  Dom ,Sax ,Pull

 Dom解析Xml 是将整个Xm文档当成一个对象来处理,会先把整个文档读入到内存里。是基于树的结构,通常需要加载整文档和构造DOM树,然后才能开始工作。

 Sax解析Xml文档,是将整个xml加入内存把解析每一个标签都当中事件来处理。

       解析一开始触发startDocument事件,在这个事件中我们可以做一些初始化的工作。

       然后每解析到一个标签都会触发如下事件startElement(开始标签)-characters(获取内容)-endElement(结束标签),这三个事件中 不断轮训的被调用,我们可以做获取内容

       最后触发endDocument事件,在这个事件中 我们可以做解析完成xml的收尾工作

 Pull解析Xml文档,跟Sax类似,是基于流(stream)操作文件,然后根据节点事件回调开发者编写的处理程序。

PS.demo中只是针对Sax及 Pul对Xml解析。l


2.解析流程

  Sax解析Xml的流程:

startDocument方法
这是第一个需要重写的方法,每处理一个XML文档都会响应一次。所以这个方法里可以写需要初始化的代码。

startElement方法
这是处理每个节点所触发的方法,通过这个方法你可以直接当前处理的节点的名称以及属性。

characters方法
当处理一个节点之间的文本时候触发该方法,但是该方法并不会告诉你当前文本的所属标签,而仅仅是告诉你文本内容。

endElement方法
遇到一个节点的结束标签时,将会出发这个方法,并且会传递结束标签的名称。

endDocument方法
如果当前的XML文档处理完毕后,将会触发该方法,在此方法内你可以将最终的结果保存并且销毁不需要使用的变量。
  流程图如下:(图片来之网络)


  Pull解析xml,类似Sax解析xml,每一个标签都会触发一个事件,针对所需的标签名获取标签的属性值及标签的内容。然后通过parse.next()方法触发下一个标签的事件,知道最后一个标签解析完毕。

流程图如下:(图片来之网络)

3.代码实现

Sax解析:(解析Assets中的nodes.xml文件)

            //调用代码如下
            AssetManager assetManager = getResources().getAssets();
            InputStream inputStream = assetManager.open("nodes.xml");
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser parser = factory.newSAXParser();
            XmlSaxHandler dh = new XmlSaxHandler(callback);//解析结束后存入数据库
            parser.parse(inputStream, dh);

            ... ...

//XmlSaxHandler 代码
public class XmlSaxHandler extends DefaultHandler {
    private static final String TAG = "XmlSaxHandler";
    private List<NodeBean> nodes ;
    private NodeBean tempNode;
    private String tempElement = "";

    private ParseEndCallback callback;

    //初始化一些重要的处理
    public XmlSaxHandler(ParseEndCallback callback){
       nodes = new ArrayList<>();//这是Java7 中针对泛型的 推断的技术哟
        this.callback = callback;
    }

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        Log.e("wzp","startDocument");
    }

    //在解析时会调用很多次
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);//空的方法 没有任何实现  可以不调用
        tempElement = qName;
        switch (qName){//在Java7 中可以使用String来组判断 之前只能使用char short int来做判断和处理
            case "root":
                break;
            case "node":
                tempNode = new NodeBean();
                break;
            case "node_id":
                break;
            case "node_name":
                break;
            case "node_address":
                break;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        String tempStr = new String(ch,start,length);
        //int len = tempStr.length();// \n 长度是1 \n\t 长度是2
        switch (tempElement){
            case "node":
                break;
            case "node_id":
                tempNode.setNode_id(tempStr);
                break;
            case "node_name":
                tempNode.setNode_name(tempStr);
                break;
            case "node_address":
                tempNode.setNode_address(tempStr);
                break;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        switch (qName){
            case "root":
                break;
            case "node":
                nodes.add(tempNode);
                break;
            case "node_id":
                break;
            case "node_name":
                break;
            case "node_address":
                break;
        }
    }

    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        Log.e("wzp","endDocument");
        if(callback != null && nodes != null)
          callback.parseCallback(nodes);
    }
}

... ...
//callback 只是一个回调接口
public interface ParseEndCallback {
    void parseCallback(List<NodeBean> datas);
}


Pull解析Xml代码如下:(解析的任务还是Assets文件夹中的文件)

    private List<studentBean> doPullParseXml(){
        List<studentBean> nodeBeanList = new ArrayList<>();//java7 中的泛型推断
        studentBean tempBean = null;
       try{
           XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
           XmlPullParser pullParser = factory.newPullParser();
           AssetManager assetManager = getAssets();
           InputStream inputStream = assetManager.open("students.xml");

           pullParser.setInput(inputStream,"UTF-8");

           int eventType = pullParser.getEventType();
           while(eventType != XmlPullParser.END_DOCUMENT){
               switch (eventType){
                   case XmlPullParser.START_DOCUMENT:
                       break;
                   case XmlPullParser.START_TAG:
                       String tagName = pullParser.getName();
                       switch (tagName){
                           case "student":
                               tempBean = new studentBean();
                               tempBean.setId(pullParser.getAttributeValue(0));
                               tempBean.setGroup(pullParser.getAttributeName(1));
                               break;
                           case "name":
                               if(tempBean != null)
                                   tempBean.setName(pullParser.getText());
                               break;
                           case "sex":
                               if(tempBean != null)
                                   tempBean.setSex(pullParser.getText());
                               break;
                           case "age":
                               if(tempBean != null)
                                   tempBean.setAge(pullParser.getText());
                               break;
                           case "email":
                               if(tempBean != null)
                                   tempBean.setEmail(pullParser.getText());
                               break;
                           case "birthday":
                               if(tempBean != null)
                                   tempBean.setBirthday(pullParser.getText());
                               break;
                           case "memo":
                               if(tempBean != null)
                                   tempBean.setMemo(pullParser.getText());
                               break;
                       }
                       break;
                   case XmlPullParser.END_TAG:
                       String name = pullParser.getName();
                       switch(name){
                           case "student":
                               if(tempBean != null)
                               nodeBeanList.add(tempBean);
                               break;
                       }
                       break;
               }

            eventType=pullParser.next();///调用的是next的方法 来获取当前的状态
           }
       }catch (Exception e){}
        return  nodeBeanList;
    }
//Student bean如下:

public class studentBean {
    public String id;
    public String group;
    public String name;
    public String age;
    public String sex;
    public String email;
    public String birthday;
    public String memo;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

4.附上源码

传送门:git@github.com:wzp09tjlg/XmlParseDemo.git


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值