当前位置:

首页 > 系统应用 > 7.2.1 Android XML数据解析

7.2.1 Android XML数据解析

本文目录

    本节引言: 前两节已经把 Android 自带的两种 HTTP 请求方式——HttpURLConnection 和 HttpClient——过了一遍。原本还以为 OkHttp 已经默认集成进系统里了,打算顺势把 OkHttp 的基础用法也一起讲掉,结果一看,还是得额外导入第三方库。那就先不着急,放到

    本节引言:

    前两节已经把 Android 自带的两种 HTTP 请求方式——HttpURLConnection 和 HttpClient——过了一遍。原本还以为 OkHttp 已经默认集成进系统里了,打算顺势把 OkHttp 的基础用法也一起讲掉,结果一看,还是得额外导入第三方库。那就先不着急,放到后面的进阶部分再展开。先把眼前这块内容吃透:这一节重点来看 Android 提供的三种 XML 数据解析方案,分别是 SAX、DOM 和 PULL。接下来,就按这三种方式逐个了解一遍。

    1.XML数据要点介绍

    首先我们来看看XML数据的一些要求以及概念:

    2.三种解析XML方法的比较

    3.SAX解析XML数据

    核心代码:

    SAX解析类:SaxHelper.ja va:

    /**
     * Created by Jay on 2015/9/8 0008.
     */
    public class SaxHelper extends DefaultHandler {
        private Person person;
        private ArrayList persons;
        //当前解析的元素标签
        private String tagName = null;
    /**
         * 当读取到文档开始标志是触发,通常在这里完成一些初始化操作
         */
        @Override
        public void startDocument() throws SAXException {
            this.persons = new ArrayList();
            Log.i("SAX", "读取到文档头,开始解析xml");
        }
    /**
         * 读到一个开始标签时调用,第二个参数为标签名,最后一个参数为属性数组
         */
        @Override
        public void startElement(String uri, String localName, String qName,
                                 Attributes attributes) throws SAXException {
            if (localName.equals("person")) {
                person = new Person();
                person.setId(Integer.parseInt(attributes.getValue("id")));
                Log.i("SAX", "开始处理person元素~");
            }
            this.tagName = localName;
        }
    /**
         * 读到到内容,第一个参数为字符串内容,后面依次为起始位置与长度
         */
    @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            //判断当前标签是否有效
            if (this.tagName != null) {
                String data = new String(ch, start, length);
                //读取标签中的内容
                if (this.tagName.equals("name")) {
                    this.person.setName(data);
                    Log.i("SAX", "处理name元素内容");
                } else if (this.tagName.equals("age")) {
                    this.person.setAge(Integer.parseInt(data));
                    Log.i("SAX", "处理age元素内容");
                }
    }
    }
    /**
         * 处理元素结束时触发,这里将对象添加到结合中
         */
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            if (localName.equals("person")) {
                this.persons.add(person);
                person = null;
                Log.i("SAX", "处理person元素结束~");
            }
            this.tagName = null;
        }
    /**
         * 读取到文档结尾时触发,
         */
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
            Log.i("SAX", "读取到文档尾,xml解析结束");
        }
    //获取persons集合
        public ArrayList getPersons() {
            return persons;
        }
    }

    然后我们在MainActivity.ja va中写上写上这样一个方法,然后要解析XML的时候调用下 就好了~

    private ArrayList readxmlForSAX() throws Exception {
        //获取文件资源建立输入流对象
        InputStream is = getAssets().open("person1.xml");
        //①创建XML解析处理器
        SaxHelper ss = new SaxHelper();
        //②得到SAX解析工厂
        SAXParserFactory factory = SAXParserFactory.newInstance();
        //③创建SAX解析器
        SAXParser parser = factory.newSAXParser();
        //④将xml解析处理器分配给解析器,对文档进行解析,将事件发送给处理器
        parser.parse(is, ss);
        is.close();
        return ss.getPersons();
    }

    一些其他的话:

    嗯,对了,忘记给大家说下我们是定义下面这样一个person1.xml文件,然后放到assets目录下的! 文件内容如下:person1.xml

    
    
        
            SAX解析
            18
        
        
            XML1
            43
        
    

    我们是把三种解析方式都糅合到一个demo中,所以最后才贴全部的效果图,这里的话,贴下打印的Log, 相信大家会对SAX解析XML流程更加明了:

    另外,外面的空白文本也是文本节点哦!解析的时候也会走这些节点!

    4.DOM解析XML数据

    核心代码:

    DomHelper.ja va

    /**
     * Created by Jay on 2015/9/8 0008.
     */
    public class DomHelper {
        public static ArrayList queryXML(Context context)
        {
            ArrayList Persons = new ArrayList();
            try {
                //①获得DOM解析器的工厂示例:
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                //②从Dom工厂中获得dom解析器
                DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
                //③把要解析的xml文件读入Dom解析器
                Document doc = dbBuilder.parse(context.getAssets().open("person2.xml"));
                System.out.println("处理该文档的DomImplemention对象=" + doc.getImplementation());
                //④得到文档中名称为person的元素的结点列表
                NodeList nList = doc.getElementsByTagName("person");
                //⑤遍历该集合,显示集合中的元素以及子元素的名字
                for(int i = 0;i < nList.getLength();i++)
                {
                    //先从Person元素开始解析
                    Element personElement = (Element) nList.item(i);
                    Person p = new Person();
                    p.setId(Integer.valueOf(personElement.getAttribute("id")));
    //获取person下的name和age的Note集合
                    NodeList childNoList = personElement.getChildNodes();
                    for(int j = 0;j < childNoList.getLength();j++)
                    {
                        Node childNode = childNoList.item(j);
                        //判断子note类型是否为元素Note
                        if(childNode.getNodeType() == Node.ELEMENT_NODE)
                        {
                            Element childElement = (Element) childNode;
                            if("name".equals(childElement.getNodeName()))
                                p.setName(childElement.getFirstChild().getNodeValue());
                            else if("age".equals(childElement.getNodeName()))
                                p.setAge(Integer.valueOf(childElement.getFirstChild().getNodeValue()));
                        }
                    }
                    Persons.add(p);
                }
            } catch (Exception e) {e.printStackTrace();}
            return Persons;
        }
    }

    代码分析:

    从代码我们就可以看出DOM解析XML的流程,先整个文件读入Dom解析器,然后形成一棵树, 然后我们可以遍历节点列表获取我们需要的数据!

    5.PULL解析XML数据

    使用PULL解析XML数据的流程:

    核心代码:

    public static ArrayList getPersons(InputStream xml)throws Exception
    {
        //XmlPullParserFactory pullPaser = XmlPullParserFactory.newInstance();
        ArrayList persons = null;
        Person person = null;
        // 创建一个xml解析的工厂  
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();  
        // 获得xml解析类的引用  
        XmlPullParser parser = factory.newPullParser();  
        parser.setInput(xml, "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:  
                if ("person".equals(parser.getName())) {  
                    person = new Person();  
                    // 取出属性值  
                    int id = Integer.parseInt(parser.getAttributeValue(0));  
                    person.setId(id);  
                } else if ("name".equals(parser.getName())) {  
                    String name = parser.nextText();// 获取该节点的内容  
                    person.setName(name);  
                } else if ("age".equals(parser.getName())) {  
                    int age = Integer.parseInt(parser.nextText());  
                    person.setAge(age);  
                }  
                break;  
            case XmlPullParser.END_TAG:  
                if ("person".equals(parser.getName())) {  
                    persons.add(person);  
                    person = null;  
                }  
                break;  
            }  
            eventType = parser.next();  
        }  
        return persons;  
    }  

    使用Pull生成xml数据的流程:

    核心代码:

    public static void sa ve(List persons, OutputStream out) throws Exception {
        XmlSerializer serializer = Xml.newSerializer();
        serializer.setOutput(out, "UTF-8");
        serializer.startDocument("UTF-8", true);
        serializer.startTag(null, "persons");
        for (Person p : persons) {
            serializer.startTag(null, "person");
            serializer.attribute(null, "id", p.getId() + "");
            serializer.startTag(null, "name");
            serializer.text(p.getName());
            serializer.endTag(null, "name");
            serializer.startTag(null, "age");
            serializer.text(p.getAge() + "");
            serializer.endTag(null, "age");
            serializer.endTag(null, "person");
        }
    serializer.endTag(null, "persons");
        serializer.endDocument();
        out.flush();
        out.close();
    }

    6.代码示例下载:

    运行效果图:

    代码下载: XMLParseDemo.zip:下载 XMLParseDemo.zip

    本节小结:

    这一节主要梳理了Android里三种常见的XML解析方式:DOM、SAX 和 PULL。放到移动端场景来看,更推荐后两种;而在这两者里,PULL 上手会更轻松一些,用起来也更顺手。这里就不再展开赘述了,代码往往比单纯讲概念更能说明问题。这一节先到这里,下一节继续看Android提供的原生 JSON 解析方式。

    本文内容来源于网友投稿,如有侵权请联系删除。
    作者最新文章
    系统应用 Android
    相关文章 更多
    win10关闭WindowsHello后如何取消开机密码
    win10关闭WindowsHello后如何取消开机密码

    Win10关闭Windows Hello后开机仍要密码?本文详解如何删除PIN码、设置netplwiz自动登录以及清空本地账户密码,解决开机免密登录问题。

    win10取消开机密码要不要关闭屏幕保护密码
    win10取消开机密码要不要关闭屏幕保护密码

    想取消Win10开机密码?先分清是启动登录还是屏保恢复。本文详解如何通过netplwiz设置自动登录,以及如何关闭屏幕保护恢复时的登录验证,同时保留睡眠唤醒的安全设置,确保操作准确且不影响电脑安全。

    win10微软账户如何取消开机密码直接进桌面
    win10微软账户如何取消开机密码直接进桌面

    想在Win10开机时跳过密码直接进入桌面?本文详解Microsoft账户下的PIN设置、本地账户切换及netplwiz自动登录配置,并区分开机验证与锁屏恢复设置,助你安全高效地优化登录体验。

    win10取消开机密码后,系统自动更新会重置设置吗?
    win10取消开机密码后,系统自动更新会重置设置吗?

    Win10系统更新后开机又要求输入密码?这通常不是密码被重置,而是自动登录设置或Windows Hello策略被更改。本文详解如何区分密码问题与登录配置问题,检查账户状态及组织策略,并安全恢复开机自动进入桌面的设置。

    XMind iOS版与安卓版功能有什么区别?
    XMind iOS版与安卓版功能有什么区别?

    XMind iOS版和安卓版都能完成完整的思维导图编辑,但在文件保存、导出格式及系统分享流程上存在差异。本文详解两端在实际使用中的不同点,帮助跨平台用户优化工作流。

    微软官网下载Win10 64位官方ISO镜像的完整步骤
    微软官网下载Win10 64位官方ISO镜像的完整步骤

    详解如何从微软官网获取纯净的Windows 10 64位ISO镜像文件,包括正确的下载入口、版本与语言选择技巧,以及下载后的完整性校验步骤,确保系统安装源安全可靠。

    Linux如何开启端口号?开放端口命令详解
    Linux如何开启端口号?开放端口命令详解

    详细讲解Linux如何开启端口号以及常用的开放端口命令。

    docker容器自动重启怎么解决 排查原因与修复方法
    docker容器自动重启怎么解决 排查原因与修复方法

    遇到Docker容器频繁自动重启?本文提供从查看容器日志、解读退出代码到配置Restart Policy的完整排查与修复方案,确保服务稳定性。

    Linux设置静态路由命令与永久生效教程
    Linux设置静态路由命令与永久生效教程

    学习如何在Linux中使用命令行添加临时静态路由,并通过修改网络配置文件实现重启后依然有效的永久静态路由设置,涵盖CentOS和Ubuntu的不同配置方法。

    摄像头连接电脑后怎么打开查看实时画面教程
    摄像头连接电脑后怎么打开查看实时画面教程

    摄像头连接电脑后不知如何查看画面?本教程演示如何使用Windows自带的“相机”应用快速调取实时视频流,无需下载额外软件,步骤简单直观,适用于大多数USB及内置摄像头。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。

    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    WINDOWS 更多
    3dmax(3ds max)
    3dmax(3ds max)
    Windows

    Autodesk 3ds Max 是一款专业的三维建模、动画与渲染软件,广泛应用于建筑可视化、游戏开发、影视动画、广告设计和产品展示等领域。

    photoshop
    photoshop
    Windows、macOS 、 iPad

    Photoshop 2026 是 Adobe 推出的专业图像处理与视觉设计软件,支持 Windows、macOS 和 iPad 等平台,广泛应用于摄影修图、电商设计、平面海报、数字绘画及视觉合成等创作场景。

    Blender
    Blender
    Windows、macOS 和 Linux

    Blender 是一款免费开源、跨平台的专业 3D 创作软件,集建模、动画、渲染、视频编辑与视觉合成等功能于一体,广泛应用于影视动画、游戏设计和建筑可视化等领域。软件支持 Cycles 物理渲染器与 Eevee 实时渲染引擎,并提供多边形建模、骨骼绑定、物理模拟等专业工具。Blender 兼容 Windows、macOS 和 Linux 系统,安装包轻巧、运行流畅,依托活跃的全球开发者社区持续更新,是从初学者到专业创作者都值得选择的正版 3D 创作工具。