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

简介: 第十一讲: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;
    }
相关文章
|
2月前
|
XML 数据采集 API
用Lxml高效解析XML格式数据:以天气API为例
免费Python教程:实战解析中国天气网XML数据,详解Lxml库高效解析技巧、XPath用法、流式处理大文件及IP封禁应对策略,助你构建稳定数据采集系统。
197 0
|
9月前
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
2179 1
|
7月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
205 2
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
7月前
|
Java Android开发
Android studio中build.gradle文件简单介绍
本文解析了Android项目中build.gradle文件的作用,包括jcenter仓库配置、模块类型定义、包名设置及依赖管理,涵盖本地、库和远程依赖的区别。
654 19
|
10月前
|
移动开发 安全 Java
Android历史版本与APK文件结构
通过以上内容,您可以全面了解Android的历史版本及其主要特性,同时掌握APK文件的结构和各部分的作用。这些知识对于理解Android应用的开发和发布过程非常重要,也有助于在实际开发中进行高效的应用管理和优化。希望这些内容对您的学习和工作有所帮助。
1040 83
|
7月前
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
1938 2
|
12月前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
2720 65
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
9月前
|
数据采集 JSON 数据可视化
JSON数据解析实战:从嵌套结构到结构化表格
在信息爆炸的时代,从杂乱数据中提取精准知识图谱是数据侦探的挑战。本文以Google Scholar为例,解析嵌套JSON数据,提取文献信息并转换为结构化表格,通过Graphviz制作技术关系图谱,揭示文献间的隐秘联系。代码涵盖代理IP、请求头设置、JSON解析及可视化,提供完整实战案例。
579 4
JSON数据解析实战:从嵌套结构到结构化表格
|
9月前
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
331 15
|
9月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。

推荐镜像

更多
  • DNS