java学习---XML&JSON

Posted 易小顺

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java学习---XML&JSON相关的知识,希望对你有一定的参考价值。

XML & JSON

1、 XML

 1.1 XML 介绍

  1.1.1 What is it?

什么是 XML?
XML 指可扩展标记语言(EXtensible Markup Language
XML 是一种标记语言,很类似 html
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义,需要自行定义标签
XML 被设计为具有自我描述性平台无关性

  1.1.2 名词解释

  • 可拓展性标记语言

    在电子计算机中,标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种的信息比如文章等。它可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。

  • 自我描述性

    XML 是独立于其他平台定义的,例如 XML 定义了一个结构,不同之间平台交换数据, XML结构不需要依赖任何平台的结构,而是自己定义的 XSD 或者 DTD,其余平台只要按照这个去解析 XML 就可以了。

  • 数据传输

    XML 文件包含了发送者和接受者的信息,同时拥有标题以及消息主体。 但是,这个 XML 文档仍然没有做任何事情,仅仅是包装了 XML 标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。

 1.2 XML 语法格式

   XML 的语法格式很简单,和 HTML 类似,但也不同(例如 XML 的标签必须闭合)

  1.2.1 文档声明

  声明写在文件的第一行,表明当前的文档是 XML 格式的文件,不写不影响读取,但是写上最好。

  • 语法格式

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    

    version 表示当前文件的版本,encoding 表示文件所使用的的字符编码,standalone 表示是否依赖其他的文件(默认是 yes )

  1.2.2 元素标记

  XML 文件中的元素以 <标记名称> 标记内容 </标记名称> 形式出现,由开发者自行定义内容。

  • 自定义名称,必须遵循以下命名规则
规则
1.名称可以含字母、数字以及其他的字符
2名称不能以数字或者标点符号开始
3.名称不能以字符 “xml”(或者 XML、Xml)开始
4.名称不能包含空格,不能包含冒号(:)
5.名称区分大小写
  • 语法格式

    <books>
        <book>
            <name>金苹果</name>
            <info>讲述了吃苹果的过程</info>
        </book>
    </books>
    

  标记内部还可以有属性字段,由 属性名 = “属性值” 组成(属性值必须有引号进行修饰)。

  • 语法格式

    <books>
        <book id="1001">
            <name>金苹果</name>
            <info>讲述了吃苹果的过程</info>
        </book>
        <book id="1002">
            <name>银苹果</name>
            <info></info>
        </book>
    </books>
    

  1.2.3 内容解析

  有些情况下我们需要在内容中定义一些和 XML 语法类型结构的特殊字符,但是不希望被解析,就需要用

CDATA 进行修饰, CDATA 部分中的所有内容都会被解析器忽略。

  • 例如 像 "<""&"字符在 XML 元素中都是非法的。

    问题
    "<" 会产生错误,因为解析器会把该字符解释为新元素的开始。
    "&" 会产生错误,因为解析器会把该字符解释为字符实体的开始。
  • 错误示范

    <books>
        <book>
            <name><金苹果></name>
            <info>讲述了你 & 他吃苹果</info>
        </book>
    </books>
    

    上述格式会报错

  • 正确格式

    <books>
        <book>
            <name><![CDATA[[<金苹果>]]></name>
            <info><![CDATA[[讲述了你 & 他吃苹果]]></info>
        </book>
    </books>
    

  1.2.4 内容注释

  和大多数的语言一样,XML 提供注释格式,由<!-- 注释内容 --> 表示, 注释不能写在文档文档声明前,也不能嵌套注释。

  • 语法格式

    <books>
        <book>
            <!--这是一个书名-->
            <name>金苹果</name>
        </book>
    </books>
    

 1.3 XML 注意问题

  1.3.1 根标记唯一

  标标记可重复定义,但是最外层的标记只能存在一个。

  • 错误示范

    <books>
        <book>
            <name>金苹果</name>
        </book>
    </books>
    <--!多个根标记将会报错-->
    <books>
        <book>
            <name>金苹果</name>
        </book>
    </books>
    

    上述文件将会报错

  1.3.2 标记不可交叉

  标记可以 嵌套 ,但是不允许标记间 交叉,标记的开始和结束都是成对出现的。

  • 错误示范

    <books>
        <book>
            <name>金苹果
        </book>
            </name>
    </books>
    

    上述文件将会报错

 1.4 XML 解析方式

  1.4.1 SAX解析

  解析方式是事件驱动机制 !逐行读取XML文件解析,每当解析到一个标签的开始 结束 内容 属性时,触发事件。 我们可以编写程序在这些事件发生时,进行相应的处理。

  • 优点

    优点
    分析能够立即开始,而不是等待所有的数据被处理。
    逐行加载,节省内存,有助于解析大于系统内存的文档。
    有时不必解析整个文档,它可以在某个条件得到满足时停止解析。
  • 缺点

    缺点
    单向解析,无法定位文档层次,无法同时访问同一文档的不同部分数据(因为逐行解析,当解析第n行是,第n-1行已经被释放了,无法再进行操作了)。
    无法得知事件发生时元素的层次,只能自己维护节点的父/子关系。
    只读解析方式,无法修改XML文档的内容。

  1.4.2 DOM解析

  是用与平台和语言无关的方式表示 XML 文档的官方W3C标准,分析该结构通常需要加载整个文档和内存中建立文档树模型。程序员可以通过操作文档树,来完成数据的 获取 修改 删除 等.

  • 优点

    优点
    文档在内存中加载, 允许对数据和结构做出更改。
    访问是双向的,可以在任何时候在树中双向解析数据。
  • 缺点

    缺点
    文档全部加载在内存中 , 消耗资源大。

  1.4.3 JDOM解析

   目的是成为 Java 特定文档模型,它简化与XML 的交互并且比使用 DOM 实现更快。由于是第一 个 Java特定模型,JDOM 一直得到大力推广和促进。

   JDOM 文档声明其目的是 使用20%(或更少)的精力解决80%(或更多)Java/XML问题

  • 优点

    优点
    使用具体类而不是接口,简化了DOM的API。
    大量使用了Java集合类,方便了Java开发人员。
  • 缺点

    缺点
    没有较好的灵活性。
    性能不是那么优异。

  1.4.4 DOM4J解析

   它是 JDOM 的一种智能分支。它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。

  它还提供了构建文档表示的选项, DOM4J 是一个非常优秀的 Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一 个开放源代码的软件。

  如今可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML。 目前许多开源项目中大量采用 DOM4J, 例如:Hibernate

2、 XML 解析 & 生成

 2.1 几个对象及方法

  2.1.1 文档对象 Document

  指的是加载到内存的整个 XML 文档.。

常用方法:
通过文档对象,获取 XML 文档中的根元素对象 Element root = doc.getRootElement();
添加根节点 Element root = doc.addElement(“根节点名称”);

  2.1.2 元素对象 Element

  指的是 XML 文档中的单个节点.。

常用方法:
获取节点名称 String getName();
获取节点内容 String getText();
设置节点内容 String setText();
根据子节点的名称,获取匹配名称的第一个子节点对象 Element element(String 子节点名称);
获取所有的子节点对象 List elements();
获取节点的属性值 String attributeValue(String 属性名称);
获取子节点的内容 String elementText(String 子节点名称);
添加子节点 Element addElement(String 子节点名称);
添加属性 addAttribute(String 属性名,String 属性值);

 2.2 DOM4J 解析

  2.2.1 解析本地文件

  没有啥可以描述的,直接按照步骤进行即可。

  • 代码测试

    public static void main(String[] args) throws IOException, DocumentException {
            // 1、   引入dom4j-1.6.1.jar包
            // 2、   xml 文件的读入流
            FileInputStream inputStream = new FileInputStream("resources/test.xml");
            // 3、   创建 xml 读取工具对象
            SAXReader reader = new SAXReader();
            // 4、   读取输入流得到文档对象
            Document document = reader.read(inputStream);
            // 5、   通过文档对象读取数据
            Element root = document.getRootElement();
            // 读取节点的名称
            System.out.println(root.getName());
            // 获取根节点下的所有子节点
            List<Element> list = root.elements();
            // 遍历节点读取数据
            for (Element element: list) {
                List<Element> nodes = element.elements();
                for (Element node: nodes) {
                    // 取出节点内容
                    System.out.println(node.getText());
                }
            }
        }
    

    输出结果

  2.2.2 解析网络文件

  和解析本地文件方法类似,只是读取文件的方法不同。

  • 代码测试

    String url = "http://...";
    URL url = new URL(url);
    // 连接 url 地址得到连接后拿到输入流对象
    URLConnection conn = url.openConnection();
    InputStream is = conn.getInputStream();
    // 后面的步骤和本地文件的方法一致
    

 2.3 XPATH 解析

  2.3.1 路径表达式

   通过路径快速的查找一个或一组元素

路径表达式
/ : 从根节点开始查找
// : 从发起查找的节点位置 查找后代节点
. : 查找当前节点
.. : 查找父节点
@ : 选择属性
  • 选择属性的使用方法

    [@属性名=‘值’] [@属性名>‘值’] [@属性名<‘值’] [@属性名!=‘值’]

  2.3.2 解析文件

  • 两种方法获取节点

    // 根据路径表达式, 查找匹配的单个节点
    Element e = selectSingleNode("路径表达式");
    
    // 根据路径表达式, 查找匹配的所有节点
    List<Element> es = selectNodes("路径表达式");
    
  • 代码测试

    public static void main(String[] args) throws IOException, DocumentException {
            // 2、   xml 文件的读入流
            FileInputStream inputStream = new FileInputStream("resources/test.xml");
            // 3、   创建 xml 读取工具对象
            SAXReader reader = new SAXReader();
            // 4、   读取输入流得到文档对象
            Document document = reader.read(inputStream);
            // 5、   读取所有匹配节点
            List<Node> names = document.selectNodes("//name");
            List<Node> info = document.selectNodes("//info");
            for(int i = 0; i < names.size(); i++) {
                System.out.println(names.get(i).getName() + ":" + names.get(i).getText());
                System.out.println(info.get(i).getName() + ":" + info.get(i).getText());
            }
        }
    

    输出结果

  • 属性查找

    public static void main(String[] args) throws IOException, DocumentException {
            // 2、   xml 文件的读入流
            FileInputStream inputStream = new FileInputStream("resources/test.xml");
            // 3、   创建 xml 读取工具对象
            SAXReader reader = new SAXReader();
            // 4、   读取输入流得到文档对象
            Document document = reader.read(inputStream);
            // 5、   获取属性 ID 为 1001 的 book 标签下的 name 标签节点
            Node node = document.selectSingleNode("//book[@id='1001']//name");
            System.out.println(node.getText());
        }
    

 2.4 XML 文件生成

  2.4.1 Document对象

  通过往 Document 文档中添加节点和相应的节点名称和内容来丰富 XML 文件信息,最终输出到本地磁盘。

  • 代码测试

        public static void main(String[] args) throws IOException, DocumentException {
            // 1、   创建一个文档对象
            Document document = DocumentHelper.createDocument();
            // 2、   添加节点后会返回当前添加的节点
            Element books = document.addElement("books");
            Element name = books.addElement("name");
            // 3、   设置节点信息
            name.setText("金苹果");
            Element info = books.addElement("info");
            info.setText("吃苹果");
            // 4、   添加节点属性
            books.addAttribute("id", "1001");
            // 5、   输出流转换
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("resources/test.xml"));
            xmlWriter.write(document);
            xmlWriter.close();
        }
    

    输出结果

  2.4.2 XStream 对象

  通过 XStream 对象可以直接将一个对象以符合 XML 语法标准的形式转换。

  • 代码测试

    public static void main(String[] args) throws IOException, DocumentException {
            FileOutputStream outputStream = new FileOutputStream("resources/test.xml") ;
            Person person = new Person("张三", 18, null);
            // 1、   创建 XStream 对象
            XStream xStream = new XStream();
            // 2、   修改节点名为 person
            xStream.alias("person", Person.class);
            // 3、   将对象转为 XML 字符串并写入到输出流
            xStream.toXML(person, outputStream);
            outputStream.close();
        }
    

    输出结果

3、 JSON 文件

 3.1 JSON 介绍

   JSON ( javascript Object Notation ) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式。 同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包。

  3.1.1 格式

  • json 文件中一个 {} 就表示一个对象, 括号中描述对象的属性,通过键值对来描述对象的属性。
属性格式
键与值之间使用冒号连接,多个键值对之间使用逗号分隔。
键值对的键应使用引号引住 (通常Java解析时,,键不使用引号会报错, 而JS能正确解析)
键值对的值,可以是 JS 中的任意类型的数据
  • 代码格式

    {
    	"name":"金苹果",
    	"info":"种苹果"
    }
    
  • 对象可嵌套

    {
        "name":"伟杰老师",
        "age":18,
        "heihei":{
            "name":"大长刀",
            "length":"40m"
        }
    }
    
  • 数组表示

    {
        "name":"伟杰老师",
        "age":18,
        "paoyou":["张三","李四","王二","麻子"],
    }
    

 3.2 java 和 json 互转

  GsonFastJson 提供转换函数们只需要将其对应的 jar 文件引入就可以使用。

  3.2.1 Gson

  Google 提供的转换工具。

  • java 对象转 JSON 字符串

    public static void main(String[] args) throws IOException, DocumentException {
            Person person = new Person("张三", 18, new String[]{"抽烟","喝酒","烫头"});
        	// 获取转换的对象
            Gson gson = new Gson();
            String s = gson.toJson(person);
            System.out.println(s);
        }
    
  • JSON 字符串转 java对象

    public static void main(String[] args) throws IOException, DocumentException {
         String json = "{\\"name\\":\\"张三\\",\\"age\\":18,\\"hobby\\":[\\"抽烟\\",\\"喝酒\\",\\"烫头\\"]}";
         Gson gson = new Gson();
         // 转换为对应对象
         Person person = gson.fromJson(json, Person.class);
         System.out.println(person);
         // 转换为 map 集合,以键值对形式对数据进行存储
         HashMap map = gson.fromJson(json, HashMap.class);
         for (Object str:map.keySet()) {
            System.out.println(map.get(str));
         }
    }
    

    输出结果

  3.2.2 FastJson

  阿里 提供的转换工具。