Android Studio 解析XML的三种方法

本文出自:http://blog.csdn.net/dt235201314/article/details/71588252

一丶概述

文件解析要求,json解析和xml解析,前面文章说过Json转实体类,这里就说说解析XML

内容:

Android Studio 解析XML常见的三种方式:DOM PULL SAX (实现XML转实体类并打印输出)

效果演示:


20170510204859624.gif

二丶正文

SAX(Simple API for XML) 使用流式处理的方式,它并不记录所读内容的相关信息。它是一种以事件为驱动的XML API,解析速度快,占用内存少。使用回调函数来实现。 缺点是不能倒退。

DOM(Document Object Model) 是一种用于XML文档的对象模型,可用于直接访问XML文档的各个部分。它是一次性全部将内容加载在内存中,生成一个树状结构,它没有涉及回调和复杂的状态管理。 缺点是加载大文档时效率低下。

Pull内置于Android系统中。也是官方解析布局文件所使用的方式。Pull与SAX有点类似,都提供了类似的事件,如开始元素和结束元素。不同的是,SAX的事件驱动是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用相应的方法。而Pull解析器并没有强制要求提供触发的方法。因为他触发的事件不是一个方法,而是一个数字。它使用方便,效率高。

SAX、DOM、Pull的比较:
1. 内存占用:SAX、Pull比DOM要好;
2. 编程方式:SAX采用事件驱动,在相应事件触发的时候,会调用用户编好的方法,也即每解析一类XML,就要编写一个新的适合该类XML的处理类。DOM是W3C的规范,Pull简洁。
3. 访问与修改:SAX采用流式解析,DOM随机访问。
4. 访问方式:SAX,Pull解析的方式是同步的,DOM逐字逐句

这里不做详细讲解,看注释,上代码

看项目文件,注意XML放的位置,不会建assets参考http://blog.csdn.net/u012861467/article/details/51773191

image.png

XML

<?xml version="1.0" encoding="UTF-8" ?>
<persons>
    <person id="23">
        <name>李雷</name>
        <age>30</age>
    </person>
    <person id="20">
        <name>韩梅梅</name>
        <age>25</age>
    </person>
</persons>

person.Java

public class Person {
    Integer id;
    String name;
    Short age;

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Short getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

XMLtoEntityActivity

public class XMLtoEntityActivity extends AppCompatActivity {
    private TextView tv_show_entity;
    private String string = "";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.xmlto_entity_activity);
        tv_show_entity = (TextView) findViewById(R.id.tv_show_entity);
    }

    public void startXML(View view){
//        SAXService saxService = new SAXService();
//        DOMService domService = new DOMService();
        PULLService pullService = new PULLService();
        try {
            InputStream inputStream = getAssets().open("Users.xml");
//            List<Person> persons = saxService.getPerson(inputStream);
//            List<Person> persons = domService.getPersons(inputStream);
            List<Person> persons = pullService.getPersons(inputStream);
            for (Person person : persons) {
                Log.e("TAG",person.toString());
                string += person.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        tv_show_entity.setText(string);
    }
}

DOM方法

/**
 * 采用DOM解析XML内容
 */

public class DOMService {
    public List<Person> getPersons(InputStream inputStream) throws Exception {

        List<Person> persons = new ArrayList<>();

        //获取DOM解析器工厂
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //获DOM解析器
        DocumentBuilder builder = factory.newDocumentBuilder();
        //将解析树放入内存,通过返回值Document来描述结果
        Document document = builder.parse(inputStream);
        //取得根元素<personos>
        Element root = document.getDocumentElement();
        //取得所有person节点集合
        NodeList personNodes = root.getElementsByTagName("person");
        for (int i = 0; i < personNodes.getLength(); i++) {
            Person person = new Person();
            //取得person节点元素
            Element personElement = (Element) personNodes.item(i);
            //取得属性值并设置ID
           person.setId(Integer.parseInt(personElement.getAttribute("id")));
            //获取person的子节点
            NodeList personChilds = personElement.getChildNodes();
            for (int j = 0; j < personChilds.getLength(); j++) {
                //判断当前节点是否是元素类型的节点
                if (personChilds.item(j).getNodeType() == Node.ELEMENT_NODE) {
                    Element childElement = (Element) personChilds.item(j);
                    if ("name".equals(childElement.getNodeName())) {
                        //获取孙节点的值
                        person.setName(childElement.getFirstChild().getNodeValue());
                    } else if ("age".equals(childElement.getNodeName())) {
                        person.setAge(Short.parseShort(childElement.getFirstChild().getNodeValue()));
                    }
                }
            }
            persons.add(person);
        }
        return persons;
    }
}

PULL方法

/**
 * 采用PULL解析XML内容
 */

public class PULLService {
    public List<Person> getPersons(InputStream inputStream) throws Exception {
        List<Person> persons = null;
        Person person = null;
        //得到PULL解析器
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(inputStream,"UTF-8");
        //产生事件
        int eventType = parser.getEventType();
        //如果不是文档结束事件就循环推进
        while (eventType != XmlPullParser.END_DOCUMENT) {
            switch (eventType) {
                case XmlPullParser.START_DOCUMENT://开始文档事件
                    persons = new ArrayList<>();
                    break;
                case XmlPullParser.START_TAG://开始元素事件
                    //获取解析器当前指向的元素的名称
                    String name = parser.getName();
                    if ("person".equals(name)) {
                        person = new Person();
                        person.setId(Integer.parseInt(parser.getAttributeValue(0)));
                    }
                    if (person != null) {
                        if ("name".equals(name)) {
                            //获取解析器当前指向元素的下一个文本节点的值
                            person.setName(parser.nextText());
                        }
                        if ("age".equals(name)) {
                            person.setAge(Short.parseShort(parser.nextText()));
                        }
                    }
                    break;
                case XmlPullParser.END_TAG://结束元素事件
                    //判断是都是person的结束事件
                    if ("person".equals(parser.getName())) {
                        persons.add(person);
                        person = null;
                    }
                    break;
            }
            //进入下一个元素并触发相应的事件
            eventType = parser.next();
        }
        return persons;
    }
}

SAX方法

/**
 * 采用SAX解析XML内容
 */

public class SAXService {
    public List<Person> getPerson(InputStream inputStream) throws Exception {
        //得到SAX解析工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();
        //得到SAX解析器
        SAXParser parser = factory.newSAXParser();
        PersonParser personParser = new PersonParser();
        parser.parse(inputStream,personParser);
        inputStream.close();
        return personParser.getPersons();
    }
    private final class PersonParser extends DefaultHandler {

        private List<Person> persons = null;
        private String tag = null;//记录当前解析到了那个元素节点名称
        private Person person;

        public List<Person> getPersons(){
            return persons;
        }
        //一开始会执行这个方法,所以在这里面完成初始化
        @Override
        public void startDocument() throws SAXException {
            persons = new ArrayList<>();
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            //判断元素节点是否等于person
            if ("person".equals(localName)) {
                person = new Person();
                //获取数据,参数为索引下标
                person.setId(Integer.parseInt(attributes.getValue(0)));
            }
            tag = localName;
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ("person".equals(localName)) {
                persons.add(person);
                person = null;
            }
            tag = null;
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            if (tag != null) {
                //获取文本节点的数据
                String data = new String(ch, start, length);
                if ("name".equals(tag)) {
                    person.setName(data);
                } else if ("age".equals(tag)) {
                    person.setAge(Short.parseShort(data));
                }
            }
        }
    }
}

总结:Android开发主流是传json,而XML解析一般跟网络请求,爬虫数据相关。当然两者也是可以相互转换的,Java只强大在于提供了很多的类和方法。只要你愿意学,方法总是有的
源码下载欢迎Star(updating):https://github.com/JinBoy23520/CoderToDeveloperByTCLer

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 一、绪论 上周工作需要了解项目的一些大体内容,结果在xml解析这一块看的迷迷糊糊的,所以在这里把学习到xm...
    cao健强阅读 3,925评论 1 7
  • 1. XML总结 1.1. XML简介 XML : 可扩展的标记语言。(和HTML非常类似的) 可扩展的。 自定义...
    Ethan_Walker阅读 2,815评论 0 12
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,012评论 8 265
  • 一. XML数据交换格式 XML数据交换格式是一种自描述的数据交互格式,虽然XML数据格式不如JSON "轻便",...
    __season____阅读 2,416评论 0 7
  • 人总是在遇到问题的时候,刻意或者不经意的去寻找答案,疯狂的去寻找,然而答案早已在心间,我想只是尽可能的寻找能支...
    空谷飞鸟阅读 331评论 0 1