第十一讲:Android中的xml和Json文件的解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 第十一讲:Android中的xml和Json文件的解析

1.数据格式的引入


在开发应用程序的时候经常性的会遇到服务器与客户端通讯,或者不同语言间数据传递与交互的情况。就这样人们就总结出了统一的数据格式来传递数据,这就是数据格式或叫做数据交换格式。

常见的数据交换格式有:

  • XML
  • JSON


2.XML数据格式简介


XML:可扩展标记语言(Extensible Markup Language XML),用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML是标准通用标记语言(SGML)的子集,非常适合Web传输,XML提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

XML和HTML或其他语言最大的区别是:XML是用来存储数据的。

XML的语言:


任何的起始标签都必须有一个结束标签。

可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟着一个斜线(/),例如.XML解析器会将其翻译成

标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签。

所有的属性都必须有值。

所有的属性都必须在值的周围加上双引号。

举例:

<?xml version="1.0" encoding="utf-8" ?>
<employees>
    <employee id="1">
        <name>张三</name>
        <gender>男</gender>
        <address>
            <homeaddress>河北省邯郸市</homeaddress>
            <workaddress>河北省石家庄市</workaddress>
        </address>
    </employee>
    <employee id="2">
        <name>李四</name>
        <gender>女</gender>
        <address>
            <homeaddress>河北省保定市</homeaddress>
            <workaddress>河北省张家口市</workaddress>
        </address>
    </employee>
</employees>

XML的特点:

1.XML被设计用来结构化存储以及传输信息。

2.XML仅仅是纯文本。

3.XML可自定义标签

4.XML和HTML不可相互替代

5.XML是W3C的推荐标准。

6.XML无所不在。

3.解析XML数据的方法

3.1DOM方式解析

特点:

先把XML文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。

一次全部加载,如果对于数据量小的情况下,它的效率还可以,如果XML文件很大的情况下。速度就会慢起来。

直接把文档调入内存中,比较耗内存。

步骤:

 private void parseStudents() throws ParserConfigurationException, IOException, SAXException {
        // 1.首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // 2.然后利用DocumentBuilderFactory创建DocumentBuilder;
        DocumentBuilder builder = factory.newDocumentBuilder();
        // 3.然后加载XML文档(Document);
        InputStream is = getAssets().open("students.xml");
        Document document = builder.parse(is);//读取xml文件,生成DOM树
        // 4.然后获取文档的根结点(Element);
        Element root = document.getDocumentElement();//获取根节点
        Log.e("根节点的名称", root.getTagName());
        // 5.然后获取根结点中所有子节点的列表(NodeList);
        NodeList studentList = root.getChildNodes();
        // 6.然后再获取子节点列表中的需要读取的结点。
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < studentList.getLength(); i++) {
            Student student = new Student();
            Node stuNode = studentList.item(i);//遍历NodeList,获取结点列表中每一个结点
            Log.e("stuNode标签", stuNode.getNodeName());
            NamedNodeMap map = stuNode.getAttributes();//获取该节点的所有属性
            if (stuNode.getNodeName().equals("student")) {
                Node genderNode = map.getNamedItem("gender");//将某一个属性转换成一个node对象
                String gender = genderNode.getTextContent();//获取节点的值
                student.setGender(gender);//为student的属性赋值
                //获取student节点的子节点列表
                NodeList childList = stuNode.getChildNodes();
                for (int j = 0; j < childList.getLength(); j++) {
                    Node childNode = childList.item(j);
                    if (childNode.getNodeName().equals("name")) {
                        String name = childNode.getTextContent();
                        student.setName(name);
                    } else if (childNode.getNodeName().equals("nickname")) {
                        String nickname = childNode.getTextContent();
                        student.setNickname(nickname);
                    }
                }
                students.add(student);
            }
        }

3.2 SAX解析方式


特点:


SAX即是:Simple API for XML.

SAX是基于事件驱动的。当然Android的事件机制是基于回调函数的,在用SAX解析XML文档时候,在读到文档开始和结束标签时候就会回调一个事件,在读到其他节点于内容时候也会回调一个事件。

步骤:


public class ParseBySAX {
    private Context context;
    private List<Student> students;
    public ParseBySAX(Context context) {
        this.context = context;
    }
    //通过SAX方式解析XML文件
    public List<Student> getStudents() throws ParserConfigurationException, SAXException, IOException {
        // 创建SAXParserFactory对象。
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 根据SAXParserFactory.newSAXParser()方法返回一个SAXParser解析器。
        SAXParser parser = factory.newSAXParser();
        //根据SAXParser解析器获取事件源对象XMLReader。
        XMLReader reader = parser.getXMLReader();
        //实例化一个DefaultHandler对象。
        MyDefaultHandler myDefaultHandler = new MyDefaultHandler();
        //连接事件源对象XMLReader到事件处理类DefaultHandler。
        reader.setContentHandler(myDefaultHandler);//绑定解析文档内容的处理器
        //调用XMLReader的parse方法从输入源中获取xml数据。
        InputStream inputStream = context.getAssets().open("students.xml");
        reader.parse(new InputSource(inputStream));
        // 通过DefaultHandler返回我们需要的数据集合。
        return students;
    }
    //解析XML时产生的事件处理器类
    private class MyDefaultHandler extends DefaultHandler {
        private String content;
        private Student student;
        //文件解析开始事件
        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            students = new ArrayList<>();
            Log.e("sax", "解析到文档开始");
        }
        //开始标签
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            student = new Student();
            Log.e("sax", "解析到开始标签" + localName);
            if (localName.equals(students)) {
                String gender = attributes.getValue("gender");
                student.setGender(gender);
            }
        }
        //标签内容
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);
            content = new String(ch, start, length);
            Log.e("sax", "标签内容" + content);//没有办法区别标签内容
        }
        //结束标签
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {//这里区分标签内容
            super.endElement(uri, localName, qName);
            Log.e("sax", "解析到结束标签");
            if (localName.equals("name")) {//证明存储到content中的数据是姓名
                student.setName(content);
            } else if (localName.equals("nickname")) {
                student.setNickname(content);
            } else if (localName.equals("student")) {
                students.add(student);
            }
        }
        //文档末尾
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
            Log.e("sax", "解析到文档末尾");
            Log.e("解析到的数据", students.toString());
        }
    }
}

3.3 PULL解析方式

20201005212253551.png

步骤:


 private List<Student> parseByPULL() throws IOException, XmlPullParserException {
        List<Student> students = new ArrayList<>();
        //创建XMLPULLParse对象
        XmlPullParser pullParser = Xml.newPullParser();
        //初始化XmlPullParser(设置Xml文件的输入流对象)
        InputStream inputStream = getAssets().open("students.xml");
        pullParser.setInput(inputStream, "UTF-8");
        //开始解析,并且返回一个事件类型
        int type = pullParser.getEventType();
        Student student = null;
        //判断事件类型不是文档末尾
        while (type != XmlPullParser.END_DOCUMENT) {
            switch (type) {
                case XmlPullParser.START_DOCUMENT:
                    //文档开始
                    break;
                case XmlPullParser.START_TAG:
                    //解析到开始标签(获取到标签的属性和内容)
                    String tagName = pullParser.getName();//获取标签的名称
                    Log.e("pull", tagName);
                    if (tagName.equals("student")) {
                        String gender = pullParser.getAttributeValue(null, "gender");
                        student = new Student();
                        student.setGender(gender);
                    } else if (tagName.equals("name")) {
                        //获取标签的内容
                        String name = pullParser.nextText();
                        student.setName(name);
                    } else if (tagName.equals("nickname")) {
                        String nickname = pullParser.nextText();
                        student.setNickname(nickname);
                    }
                    break;
                case XmlPullParser.END_TAG://结束标签
                    //解析到结束标签
                    if (pullParser.getName().equals("student")) {
                        students.add(student);
                    } else if (pullParser.getName().equals("students")) {
                        Log.e("解析结果", students.toString());
                    }
                    break;
            }
            //继续解析下一个事件类型
            type = pullParser.next();
        }
        return students;

4.JSON数据格式简介


JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。

JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从客户端传递给服务器端程序。这个字符串看起来有点儿古怪,但是 JavaScript 很容易解释它,而且 JSON 可以表示比"名称 / 值对"更复杂的结构。例如,可以表示数组和复杂的对象,而不仅仅是键和值的简单列表。

JSON基本的结构有两种:

“名称/值”对的集合(a collection of name/value pairs)。不同的语言中,它被理解为对象(object),记录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。

值的有序列表(an ordered list of values)。在大部分语言中,它被理解为数组(array)


5.解析JSON数据的方法


1.把用户对象的数据转换成JSON格式的字符串


 public String object2JSON(User user) throws JSONException {
        JSONObject jsonObject=new JSONObject();
        jsonObject.put("username",user.getUserName());
        jsonObject.put("password",user.getPassWord());
        return jsonObject.toString();
    }

2.把JSON格式的字符串转换成用户对象

public User json2Object(String jsonStr) throws JSONException {
        User user=new User();
        JSONObject jsonObject=new JSONObject(jsonStr);
        user.setUserName(jsonObject.getString("username"));
        user.setPassWord(jsonObject.getString("password"));
        return user;
    }
相关文章
|
1月前
|
Java 开发工具 Android开发
Android与iOS开发环境搭建全解析####
本文深入探讨了Android与iOS两大移动操作系统的开发环境搭建流程,旨在为初学者及有一定基础的开发者提供详尽指南。我们将从开发工具的选择、环境配置到第一个简单应用的创建,一步步引导读者步入移动应用开发的殿堂。无论你是Android Studio的新手还是Xcode的探索者,本文都将为你扫清开发道路上的障碍,助你快速上手并享受跨平台移动开发的乐趣。 ####
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
77 2
|
25天前
|
存储 Linux API
深入探索Android系统架构:从内核到应用层的全面解析
本文旨在为读者提供一份详尽的Android系统架构分析,从底层的Linux内核到顶层的应用程序框架。我们将探讨Android系统的模块化设计、各层之间的交互机制以及它们如何共同协作以支持丰富多样的应用生态。通过本篇文章,开发者和爱好者可以更深入理解Android平台的工作原理,从而优化开发流程和提升应用性能。
|
1月前
|
消息中间件 存储 Java
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
42 3
|
1月前
|
XML Android开发 数据格式
Eclipse 创建 XML 文件
Eclipse 创建 XML 文件
28 2
|
1月前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
146 8
|
1月前
|
存储
文件太大不能拷贝到U盘怎么办?实用解决方案全解析
当我们试图将一个大文件拷贝到U盘时,却突然跳出提示“对于目标文件系统目标文件过大”。这种情况让人感到迷茫,尤其是在急需备份或传输数据的时候。那么,文件太大为什么会无法拷贝到U盘?又该如何解决?本文将详细分析这背后的原因,并提供几个实用的方法,帮助你顺利将文件传输到U盘。
|
2月前
|
XML JSON 数据可视化
数据集学习笔记(二): 转换不同类型的数据集用于模型训练(XML、VOC、YOLO、COCO、JSON、PNG)
本文详细介绍了不同数据集格式之间的转换方法,包括YOLO、VOC、COCO、JSON、TXT和PNG等格式,以及如何可视化验证数据集。
349 1
数据集学习笔记(二): 转换不同类型的数据集用于模型训练(XML、VOC、YOLO、COCO、JSON、PNG)
|
1月前
|
安全 Java Linux
深入解析Android系统架构及其对开发者的意义####
【10月更文挑战第21天】 本文旨在为读者揭开Android操作系统架构的神秘面纱,探讨其如何塑造现代移动应用开发格局。通过剖析Linux内核、硬件抽象层、运行时环境及应用程序框架等关键组件,揭示Android平台的强大功能与灵活性。文章强调了理解Android架构对于开发者优化应用性能、提升用户体验的重要性,并展望了未来技术趋势下Android的发展方向。 ####
47 0
|
2月前
|
数据安全/隐私保护 流计算 开发者
python知识点100篇系列(18)-解析m3u8文件的下载视频
【10月更文挑战第6天】m3u8是苹果公司推出的一种视频播放标准,采用UTF-8编码,主要用于记录视频的网络地址。HLS(Http Live Streaming)是苹果公司提出的一种基于HTTP的流媒体传输协议,通过m3u8索引文件按序访问ts文件,实现音视频播放。本文介绍了如何通过浏览器找到m3u8文件,解析m3u8文件获取ts文件地址,下载ts文件并解密(如有必要),最后使用ffmpeg合并ts文件为mp4文件。

推荐镜像

更多