第十一讲: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;
    }
相关文章
|
3月前
|
数据采集 监控 API
告别手动埋点!Android 无侵入式数据采集方案深度解析
传统的Android应用监控方案需要开发者在代码中手动添加埋点,不仅侵入性强、工作量大,还难以维护。本文深入探讨了基于字节码插桩技术的无侵入式数据采集方案,通过Gradle插件 + AGP API + ASM的技术组合,实现对应用性能、用户行为、网络请求等全方位监控,真正做到零侵入、易集成、高稳定。
598 51
|
4月前
|
JSON 缓存 自然语言处理
多语言实时数据微店商品详情API:技术实现与JSON数据解析指南
通过以上技术实现与解析指南,开发者可高效构建支持多语言的实时商品详情系统,满足全球化电商场景需求。
|
6月前
|
存储 JSON 关系型数据库
【干货满满】解密 API 数据解析:从 JSON 到数据库存储的完整流程
本文详解电商API开发中JSON数据解析与数据库存储的全流程,涵盖数据提取、清洗、转换及优化策略,结合Python实战代码与主流数据库方案,助开发者构建高效、可靠的数据处理管道。
|
5月前
|
JSON 算法 API
淘宝商品评论API接口核心解析,json数据返回
淘宝商品评论API是淘宝开放平台提供的数据服务接口,允许开发者通过编程方式获取指定商品的用户评价数据,包括文字、图片、视频评论及评分等。其核心价值在于:
|
3月前
|
JSON Java Go
【GoGin】(2)数据解析和绑定:结构体分析,包括JSON解析、form解析、URL解析,区分绑定的Bind方法
bind或bindXXX函数(后文中我们统一都叫bind函数)的作用就是将,以方便后续业务逻辑的处理。
305 3
|
3月前
|
XML JSON 数据处理
超越JSON:Python结构化数据处理模块全解析
本文深入解析Python中12个核心数据处理模块,涵盖csv、pandas、pickle、shelve、struct、configparser、xml、numpy、array、sqlite3和msgpack,覆盖表格处理、序列化、配置管理、科学计算等六大场景,结合真实案例与决策树,助你高效应对各类数据挑战。(238字)
250 0
|
7月前
|
JSON 定位技术 PHP
PHP技巧:解析JSON及提取数据
这就是在PHP世界里探索JSON数据的艺术。这场狩猎不仅仅是为了获得数据,而是一种透彻理解数据结构的行动,让数据在你的编码海洋中畅游。通过这次冒险,你已经掌握了打开数据宝箱的钥匙。紧握它,让你在编程世界中随心所欲地航行。
252 67
|
4月前
|
JSON 自然语言处理 API
多语言实时数据淘宝商品评论API:技术实现与JSON数据解析指南
淘宝商品评论多语言实时采集需结合官方API与后处理技术实现。建议优先通过地域站点适配获取本地化评论,辅以机器翻译完成多语言转换。在合规前提下,企业可构建多语言评论数据库,支撑全球化市场分析与产品优化。
|
9月前
|
XML JSON API
如何在 Postman 中上传文件和 JSON 数据
如果你想在 Postman 中同时上传文件和 JSON 数据,本文将带你一步一步地了解整个过程,包括最佳实践和技巧,让你的工作更轻松。
|
7月前
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
353 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡

热门文章

最新文章

推荐镜像

更多