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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 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 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
157 1
|
1月前
|
数据采集 JSON 数据可视化
JSON数据解析实战:从嵌套结构到结构化表格
在信息爆炸的时代,从杂乱数据中提取精准知识图谱是数据侦探的挑战。本文以Google Scholar为例,解析嵌套JSON数据,提取文献信息并转换为结构化表格,通过Graphviz制作技术关系图谱,揭示文献间的隐秘联系。代码涵盖代理IP、请求头设置、JSON解析及可视化,提供完整实战案例。
181 4
JSON数据解析实战:从嵌套结构到结构化表格
|
1月前
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
73 15
|
1月前
|
监控 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) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
3月前
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
3月前
|
JSON 小程序 UED
微信小程序 app.json 配置文件解析与应用
本文介绍了微信小程序中 `app.json` 配置文件的详细
556 12
|
3月前
|
JSON 缓存 API
解析电商商品详情API接口系列,json数据示例参考
电商商品详情API接口是电商平台的重要组成部分,提供了商品的详细信息,支持用户进行商品浏览和购买决策。通过合理的API设计和优化,可以提升系统性能和用户体验。希望本文的解析和示例能够为开发者提供参考,帮助构建高效、可靠的电商系统。
98 12
|
1月前
|
算法 测试技术 C语言
深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
170 29
|
1月前
|
前端开发 数据安全/隐私保护 CDN
二次元聚合短视频解析去水印系统源码
二次元聚合短视频解析去水印系统源码
59 3
|
1月前
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

推荐镜像

更多
下一篇
oss创建bucket