Android使用Sax 及Pull 解析Xml demo

来源:互联网 发布:淘宝店铺监管会怎么样 编辑:程序博客网 时间:2024/06/04 19:02

客户端开发中,越来越多的接口使用的数据传输类型时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