Android Studio 解析XML的三种方法

作者: 天一方蓝 | 来源:发表于2018-07-30 21:56 被阅读48次

    本文出自: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

    相关文章

      网友评论

      本文标题:Android Studio 解析XML的三种方法

      本文链接:https://www.haomeiwen.com/subject/oneqvftx.html