第十一讲: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;
    }
相关文章
|
3天前
|
XML Java 数据格式
java解析xml文件内容
java解析xml文件内容
10 0
|
2天前
|
Android开发 开发者
Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。
【6月更文挑战第26天】Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。要更改主题,首先在该文件中创建新主题,如`MyAppTheme`,覆盖所需属性。然后,在`AndroidManifest.xml`中应用主题至应用或特定Activity。运行时切换主题可通过重新设置并重启Activity实现,或使用`setTheme`和`recreate()`方法。这允许开发者定制界面并与品牌指南匹配,或提供多主题选项。
16 6
|
1天前
|
XML 数据格式
连接Libvirtd返回XML解析
连接Libvirtd返回XML解析
13 3
|
2天前
|
XML JavaScript Java
Java解析XML
Java解析XML
|
1天前
|
机器学习/深度学习 存储 算法
技术好文:ttf文件结构解析
技术好文:ttf文件结构解析
|
1天前
|
XML JSON 开发框架
一篇文章讲明白JSON格式转换成XML格式
一篇文章讲明白JSON格式转换成XML格式
|
1天前
|
XML JSON 开发框架
一篇文章讲明白JSON格式转换成XML格式
一篇文章讲明白JSON格式转换成XML格式
|
1天前
|
XML Java 数据格式
SpringMVC的XML配置解析-spring18
SpringMVC的XML配置解析-spring18
|
1天前
|
Android开发 开发者
“List of Devices Attached“:Android设备连接问题解析
“List of Devices Attached“:Android设备连接问题解析
|
2天前
|
XML Web App开发 JavaScript
XML DOM 解析器
XML DOM解析器在浏览器中内置,将XML转换为JavaScript对象以便操作。通过XMLHttpRequest或ActiveXObject加载XML文档,如`books.xml`,然后使用`.responseXML`获取DOM。这允许遍历、修改XML节点。示例展示了如何使用AJAX加载XML。

推荐镜像

更多