XML、JSON学习大全

文章目录

    • XML:
      • 一、概念:
        • 1. 功能
        • 2. xml与html的区别
      • 二、语法格式以及特点
        • 1. XML文档声明
        • 2. 标记(元素 / 标签 / 节点)
        • 3. 一个XML文档中,必须有且仅有一个根标记
        • 4. 标记可以嵌套,但是不允许交叉
        • 5. 标记的层级称呼
        • 6. 标记名称允许重复
        • 7. 标记除了开始和结束,还有属性
        • 8. 注释
        • 9. CDATA区域
        • 10. 命名空间
      • 三、面试题
      • 四、解析
        • 1. DOM4J解析XML
        • 2. 文档对象 Document
        • 3. 元素对象 Element
        • 4. 实例
        • 5. DOM4J - XPATH解析XML
        • 6. Java生成XML
        • 7. XStream 的使用
    • JSON:
      • 1. 对象格式
      • 2. 数组格式
      • 3. 案例
      • 4. Java对象与JSON相互转换
        • 1.Gson(谷歌)
        • 2. FastJson(阿里)
        • 3. JackSon

XML:

一、概念:

Extensible Markup Language 可扩展标记语言

1. 功能

1. 存储数据
2. 配置文件
3. 在网络中传输(现在常用JSON,它的解析效率更高)

2. xml与html的区别

1. xml标签都是自定义的,html标签是预定义。
2. xml的语法严格,html语法松散
3. xml是存储数据的,html是展示数据

二、语法格式以及特点

1. XML文档声明

2. 标记(元素 / 标签 / 节点)

XML文档,由一个个的标记组成。

语法:

  • 开始标记(开放标记):<标记名称>
  • 结束标记(闭合标记):<标记名称>
  • 标记名称:自定义名称,必须遵循以下的命名规则
    • 1.名称可以包含字母、数字以及其他字符
      2.名称不能以数字或者标点符号开始
      3.名称不能以字符“xml”(或者XML、Xml)开始
      4.名称不能包含空格,不能包含冒号(:)
      5.名称区分大小写
  • 标记内容:开始标记与结束标记之间,是标记的内容
  • 例如:
<name>Tomname>

3. 一个XML文档中,必须有且仅有一个根标记

正例:

<names>
	<name>张三name>
    <name>李四name>
names>

反例:

	<name>张三name>
    <name>李四name>

4. 标记可以嵌套,但是不允许交叉

正例:

<person>
    <name>张三name>
    <age>18age>
person>

反例:

<person>
    <name>张三<age>name>
    18age>
person>

5. 标记的层级称呼

子标记,父标记,兄弟标记,后代标记,祖先标记

6. 标记名称允许重复

7. 标记除了开始和结束,还有属性

  • 标记中的属性,在标记开始时描述,由属性名和属性值组成

  • 格式:

    • 在开始标记中描述属性
    • 可以包含0~n个属性,每一个属性是一个键值对
    • 属性不允许重复,键与值之间使用等号连接,多属性之间使用空格分割
    • 属性值 必须被引号包住
  • 案例:

    <person>
        <person id="1001" groupid="1">
        	<name>Tomname>
            <age>18age>
        person>
        <person id="1003" groupid="1">
        	<name>Lucyname>
            <age>20age>
        person>
    person>
    
    

8. 注释

  • 注释不能写在文档声明前
  • 注释不能嵌套注释
    • 格式:
      注释开始:

9. CDATA区域

  • CDATA是一个不应该由XML解析器解析的文本数据区。
  • 像”<“和”&“字符在XML元素中都是非法的。
  • ”<“会产生错误,因为解析器会把该字符解释为新元素的开始。
  • ”&“会产生错误,因为解析器会把该字符解释为字符实体的开始。
  • 某些文本,比如JavaScript代码,包含大量的"<"和“&”字符。为了避免错误,可以把脚本代码定义为CDATA。
    -== CDATA部分中的所有内容都会被解析器忽略。==
  • CDATA格式:

实例:

哈哈]]>

10. 命名空间

约束规定xml文档的书写规则,限制它的可扩展性

作为框架的使用者(程序员):

  1. 能够在xml中引入约束文档
  2. 能够简单的读懂约束文档

分类:

  1. DTD:一种简单的约束技术Schema:一种复杂的约束技术。

    引入dtd文档到xml文档中:

  • 内部dtd:将约束规则定义在xml文档中
  • 外部dtd:将约束的规则定义在外部的dtd文件中
  • 本地:
  • 网络:
  1. Schema:一种复杂的约束技术。

    引入:

  • 1.填写xml文档的根元素
  • 2.引入xsi前缀. xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
  • 3.引入xsd文件命名空间. xsi:schemaLocation=“http://www.java.cn/xml student.xsd”
  • 4.为每一个xsd约束声明一个前缀,作为标识 xmlns=“http://www.java.cn/xml”

实例:

<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	      xsi:schemaLocation="http://www.java.cn/xml  student.xsd"
          xmlns="http://www.java.cn/xml">

三、面试题

问:Java中有几种XML解析方式?分别是什么?有什么样的优缺点?

答:四种

  1. SAX解析(Simple API For XML)

    解析方式是事件驱动机制!

    SAX解析器,逐行读取XML文件解析,每当解析到一个标签的开始/结束/属性/内容时,触发事件,

    我们可以编写程序在这些事件发生时,进行相应的处理

    优点

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

    缺点

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

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

    优点

    • 文档在内存中加载,允许对结构和数据进行修改
    • 访问是双向的,可以在任何时候对树中的数据进行双向解析

    缺点

    • 文档全部加载到内存中,消耗资源较大
  3. JDOM解析(Java Document Object Model)

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

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

    优点

    • 使用具体类而不是接口,简化了DOMAPI
    • 大量使用了Java集合类,方便Java开发人员

    缺点

    • 没有较好的灵活性
    • 性能不是那么优异
  4. DOM4J解析

    它是JDOM的智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath支持、XMLSchema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,DOM4J是非常优秀的Java XML API,具有性能优异、功能强大和非常易于使用的特点,同时它也是一个开放源码的软件。有越来越多的Java软件都在使用DOM4J来读写XML。

    目前许多开源项目中大量采用了JDOM技术,例如Hibernate

四、解析

1. DOM4J解析XML

步骤:

  • 1.引入jar文件 dom4j . jar
  • 2.创建一个指向XML文件的输入流
    • FileInputStream fis = new FileInputStream(“xml文件的地址”);
  • 3.创建一个xml读取工具对象
    • SAXReader sr = new SAXReader();
  • 4.使用读取工具对象,读取XML读取文档的输入流,并得到文档对象
    • Document doc = sr.read(fis);
  • 5.通过文档对象,获取XML文档中的根元素对象
    • Element root = doc.getRootElement();

2. 文档对象 Document

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

常用方法:

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

3. 元素对象 Element

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

常用方法:

  • 1.获取节点名称
    • String getName();
  • 2.获取节点内容
    • String getText();
  • 3.获取全部该节点的全部子节点
    • List elements();
  • 4.获取下一级节点中某一个节点的内容
    • String elementText(“下一级节点中某一个节点名”);

4. 实例

实例1:解析本地文件

XML文件:Students.xml


<students>
    <student id="1002">
        <name>张三name>
        <age>18age>
    student>
    <student id="1003">
        <name>李四name>
        <age>15age>
    student>
    <student id="1004">
        <name>王二name>
        <age>22age>
    student>
students>

解析程序:

public static void main(String[] args) throws DocumentException, IOException {
     
        //1. 获取文件的输入流
        FileInputStream fis = new
                FileInputStream("E:\\Students.xml");
        //2. 创建XML读取工具对象
        SAXReader sr = new SAXReader();
        //3. 通过读取工具, 读取XML文档的输入流 , 并得到文档对象
        Document doc = sr.read(fis);
        //4. 通过文档对象 , 获取文档的根节点对象
        Element root = doc.getRootElement();
        //5. 通过根节点, 获取所有子节点
        List<Element> es = root.elements();
        //6. 循环遍历三个book
        for (Element e : es) {
     
        //1. 获取id属性值
            String id = e.attributeValue("id");
        //2. 获取子节点name , 并获取它的内容
            String name = e.element("name").getText();
        //3. 获取子节点age , 并获取它的内容
            String age = e.element("age").getText();
            System.out.println("id="+id+",name="+name+",age="+age);
        }
    	fis.close();
    }

实例2:解析网络文件

一个公共的手机号查询网址:“http://apis.juhe.cn/mobile/get?phone=”+phone+"&dtype=xml&key=9f3923e8f87flea50ed4ec8c39cc9253"

juhe是一个服务接口网站,直接百度“api平台”

网络资源浏览器访问结果:

<root>
	<resultcode>101resultcode>
	<reason>错误的请求KEYreason>
	<result/>
	<error_code>10001error_code>
root>

解析程序:

public static void main(String[] args) throws IOException, DocumentException {
     
        //1. 获取XML资源的输入流
        String phone = "18516955565";
        URL url = new URL("http://apis.juhe.cn/mobile/get?phone="+phone+"&dtype=xml&key=9f3923e8f87flea50ed4ec8c39cc9253");
        URLConnection conn = url.openConnection();
        //2. 创建一个XML读取对象
        SAXReader sr = new SAXReader();
        //3. 通过读取对象 读取XML数据,并返回文档对象
        Document doc = sr.read(conn.getInputStream());
        //4. 获取根节点
        Element root = doc.getRootElement();
        //5. 解析内容
        List elements = root.elements();
        String code = root.elementText("resultcode");
        if("200".equals(code)){
     
            Element result = root.element("result");
            String province = result.elementText("province");
            String city = result.elementText("city");
            if(province.equals(city)){
     
                System.out.println("手机号码归属地为:"+city);
            }else{
     
                System.out.println("手机号码归属地为:"+"province"+"city");
            }
        }else{
     
            System.out.println("请输入正确的手机号码");
        }
    }

5. DOM4J - XPATH解析XML

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

路径表达式:

  • / : 从根节点开始查找
  • // : 从发起查找的节点位置 查找后代节点 ***
  • . : 查找当前节点
  • … : 查找父节点
  • @ : 选择属性 *
    属性使用方式:
    [@属性名=‘值’]
    [@属性名>‘值’]
    [@属性名<‘值’]
    [@属性名!=‘值’]
  • 例子:以上面的Students.xml为例
    • 路径://student[@id=‘1’]//name
    • 查找到id位1的student的name

使用步骤

通过Node类的两个方法, 来完成查找:
(Node是 Document 与 Element 的父接口)

方法1.
//根据路径表达式, 查找匹配的单个节点
Element e = doc.selectSingleNode("路径表达式");
方法2.
List es = doc.selectNodes("路径表达式");

实例:

public static void main(String[] args) throws DocumentException, IOException {
     
        //1. 获取文件的输入流
        FileInputStream fis = new
                FileInputStream("E:\\Students.xml");
        //2. 创建XML读取工具对象
        SAXReader sr = new SAXReader();
        //3. 通过读取工具, 读取XML文档的输入流 , 并得到文档对象
        Document doc = sr.read(fis);
        //4. 通过文档对象+xpath,查找所有的name节点
        List<Node> names = doc.selectNodes("//name");
        for (int i = 0; i <names.size() ; i++) {
     
            System.out.println(names.get(i).getName());
            System.out.println(names.get(i).getText());
        }
    	//5.查找单个对象
    		//5.1 用selectNodes查找
    	List<Node> names = doc.selectNodes("//student[@id=1003]//name");
        for (int i = 0; i <names.size() ; i++) {
     
            System.out.println(names.get(i).getName());
            System.out.println(names.get(i).getText());
        }
    		//5.2 用selectSingleNode查找(!!!推荐)
        Node name = doc.selectSingleNode("//student[@id=1003]//name");
        System.out.println(name.getName());
        System.out.println(name.getText());
        fis.close();
    }

用XPath只是操作起来更简单,因为底层封装了很多方法,效率并不会提高

6. Java生成XML

步骤:

1. 通过文档帮助器 (DocumentHelper) , 创建空的文档对象
Document doc = DocumentHelper.createDocument();
2. 通过文档对象, 向其中添加根节点
Element root = doc.addElement(“根节点名称”);
3. 通过根节点对象root , 丰富我们的子节点
Element e = root.addElement(“元素名称”);
4. 创建一个文件输出流 ,用于存储XML文件
FileOutputStream fos = new FileOutputStream(“要存储的位置”);
5. 将文件输出流, 转换为XML文档输出流
XMLWriter xw = new XMLWriter(fos);
6. 写出文档
xw.write(doc);
7. 释放资源
xw.close();

案例:

public static void main(String[] args) throws IOException {
     
        //1. 通过文档帮助器 (DocumentHelper) , 创建空的文档对象
        Document doc = DocumentHelper.createDocument();
        //2. 通过文档对象,向其中添加根节点
        Element Students = doc.addElement("Students");
        //3. 向根节点中 丰富子节点
        for (int i = 0; i < 100; i++) {
     
            //向根节点中加入100个student节点
            Element Student = Students.addElement("Student");
            //向Student加入id属性
            Student.addAttribute("id",1+i+"");
            //向Student中加入name和age节点
            Element name = Student.addElement("name");
            Element age = Student.addElement("age");
            name.setText("马保国"+1+i+"号");
            age.setText("哈哈哈"+i);
        }
        //4. 创建文件的输入流
        FileOutputStream fos = new FileOutputStream("E:\\Student1.xml");
        //5. 将文件输出流转为XML文档输出流
        XMLWriter xw = new XMLWriter(fos);
        //6.写出文档
        xw.write(doc);
        //7. 释放资源
        xw.close();
        System.out.println("代码执行完毕");
    }

7. XStream 的使用

作用:快速的将Java中的对象, 转换为 XML字符串

使用步骤:

1. 创建XStream 对象
XStream x = new XStream();
2. 修改类生成的节点名称 (默认节点名称为 包名.类名)
x.alias(“节点名称”,类名.class);
3. 传入对象 , 生成XML字符串
String xml字符串 = x.toXML(对象);

案例:

public static void main(String[] args) {
     
        Student s1 = new Student("张三", 18);
        Student s2 = new Student("Tom", 16);
        Student s3 = new Student("老马", 58);
        //1. 创建XStream对象
        XStream x = new XStream();
        //2. 修改生成的节点名称
        x.alias("Student",Student.class);
        //3.生成XML字符串
        String xml = x.toXML(s1);
        System.out.println(xml);
        System.out.println("-----------------------------");
        //生成一组对象的XML
        List<Student> ss = new ArrayList<>();
        x.alias("Students",List.class);
        ss.add(s1);
        ss.add(s2);
        ss.add(s3);
        String xml2 = x.toXML(ss);
        System.out.println(xml2);
    }
    static class Student{
     
        private String name;
        private int age;
        public Student() {
     
        }
        public Student(String name, int age) {
     
            this.name = name;
            this.age = age;
        }
    }

运行结果:

<Student>
  <name>张三name>
  <age>18age>
Student>
-----------------------------
<Students>
  <Student>
    <name>张三name>
    <age>18age>
  Student>
  <Student>
    <name>Tomname>
    <age>16age>
  Student>
  <Student>
    <name>老马name>
    <age>58age>
  Student>
Students>

JSON:

简介:
JSON: JavaScript Object Notation JS对象简谱 , 是一种轻量级的数据交换格式。

百度搜索:"JSON在线视图查看工具",可以查看一个难以理解的JSON文本

eg:打开网址:sojson.com/json,然后复制JSON文本进去,就能层级显示JSON

1. 对象格式

一本书

  • 书名
  • 简介

java:

class Book{
     
	private String name;
	private String info;
    get/set...
}
Book b = new Book();
b.setName(“金苹果”);
b.setInfo(“种苹果”);
...

js:

var b = new Object();
b.name = "金苹果";
b.info = "种苹果";

XML:

<book>
    <name>金苹果name>
    <info>种苹果info>
book>

JSON:

{
     
    "name":"金苹果""info":"种苹果"
}

一个对象, 由一个大括号表示
括号中 描述对象的属性 通过键值对来描述对象的属性
(可以理解为, 大括号中, 包含的是一个个的键值对.)
格式:

  • 键与值之间使用冒号连接, 多个键值对之间使用逗号分隔.
  • 键值对的键 应使用引号引住 (通常Java解析时, 键不使用引号会报错. 而JS能正确解析。)
  • 键值对的值, 可以是JS中的任意类型的数据

2. 数组格式

在JSON格式中可以与对象互相嵌套
[元素1,元素2…]

3. 案例

{
     
    "name":"马保国",
    "age":58,
    "friend":["张三","李四","王二","麻子",{
     
				"name":"卢本伟",
				"info":"老子从不开挂"
			}],
	"knife":{
     
		"name":"大长刀",
		"length":"40m"
	}
}

4. Java对象与JSON相互转换

JSON解析器
常见的解析器:Jsonlib,Gson,fastjson,jackson

1.Gson(谷歌)

最好使用最新jar包(百度搜索Gson然后去GitHub上找,或者Maven上也有)

1. JSON转为Java对象

  • 1.引入JAR包
  • 2. 创建Gson对象
    • Gson g = new Gson();
  • 调用" Object obj = g.fromJson(JSON字符串,对象类型.class) ";进行转换

创建一个Student类:

public class Student {
     
    private int id;
    private String name;
    private int age;

    public Student(int id, String name, int age) {
     
        this.id = id;
        this.name = name;
        this.age = age;
    }
    
    @Override
    public String toString() {
     
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public int getId() {
     
        return id;
    }

    public void setId(int id) {
     
        this.id = id;
    }

    public String getName() {
     
        return name;
    }

    public void setName(String name) {
     
        this.name = name;
    }

    public int getAge() {
     
        return age;
    }

    public void setAge(int age) {
     
        this.age = age;
    }
}

实例:

public static void main(String[] args) {
     
        //1. 创建Gson对象
        Gson g = new Gson();
        //2. 转换
        String str = "{\"id\":1,\"name\":\"马保国\",\"age\":56}\n";
        Student student = g.fromJson(str, Student.class);
        System.out.println(student);
        System.out.println("---------------------------");
        //3.集合转换
        String str2 = "{\"id\":1,\"name\":\"马保国\",\"age\":56,\"page\":[\"hello\",\"java\",\"hahaha\"]}\n";
        HashMap data = g.fromJson(str2, HashMap.class);
        List page = (List) data.get("page");//JSON中的数组转出来是ArrayList
        System.out.println(page.get(1));
    }

运行结果:

Student{id=1, name='马保国', age=56}
----------------------------------
java

2.Java对象转换JSON

  • 1.引入JAR包

  • 2. 创建Gson对象

    • Gson g = new Gson();
  • 3.调用" String json = g.toJSON(要转换的对象) "进行转换

实例:

public static void main(String[] args) {
     
        //1. 创建Gson对象
        Gson g = new Gson();
        //2. 转换
        Student student1 = new Student(1,"马保国",56);
        String str = g.toJson(student1);
        System.out.println(str);
        System.out.println("--------------------------------------------");
        //3. 多个对象转换
        Student student2 = new Student(2,"卢本伟",28);
        Student student3 = new Student(3,"蔡徐坤",15);
        ArrayList<Student> students = new ArrayList<>();
        students.add(student1);
        students.add(student2);
        students.add(student3);
        String str2 = g.toJson(students);
        System.out.println(str2);
    }

运行结果:

{"id":1,"name":"马保国","age":56}
--------------------------------------------
[{"id":1,"name":"马保国","age":56},{"id":2,"name":"卢本伟","age":28},{"id":3,"name":"蔡徐坤","age":15}]

2. FastJson(阿里)

最好使用最新jar包(百度搜索Gson然后去GitHub上找,或者Maven上也有)
1. JSON转为Java对象

  • 1.引入JAR包
  • 2.在需要转换Java对象的位置, 编写如下代码:
    • 类型 对象名=JSON.parseObject(JSON字符串, 类型.class);
    • 或List<类型> list=JSON.parseArray(JSON字符串,类型.class);

实例:

public class Demo4 {
     
    public static void main(String[] args) {
     
        String str = "{\"id\":1,\"name\":\"马保国\",\"age\":56}";
        Student student = JSON.parseObject(str, Student.class);
        System.out.println(student);
    }
}

运行结果:

Student{id=1, name='马保国', age=56}

2.Java对象转换JSON

  • 1.引入JAR包
  • 2.在需要转换JSON字符串的位置编写如下代码即可:
    • String json=JSON.toJSONString(要转换的对象);

实例:

public static void main(String[] args) {
     
    Student student1 = new Student(1,"马保国",56);
    String str = JSON.toJSONString(student1);
    System.out.println(str.length());
}

运行结果:

{"id":1,"name":"马保国","age":56}

注意:

FastJson是靠对象属性的get、Set方法生成josn文件的,没有get、set方法无法生成

3. JackSon

1. JSON转为Java对象

  • 1.导入jackson的相关jar包
  • 2.创建Jackson核心对象 ObjectMapper
  • 3.调用ObjectMapper的相关方法进行转换
    • readValue(json字符串数据,Class)

2. Java对象转换JSON
使用步骤:

  • 1.导入jackson的相关jar包
  • 2.创建Jackson核心对象 ObjectMapper
  • 3.调用ObjectMapper的相关方法进行转换
    • 1.转换方法:
      writeValue(参数1,obj):
      参数1:
      File:将obj对象转换为JSON字符串,并保存到指定的文件中
      Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中
      OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中
      writeValueAsString(obj):将对象转为json字符串

    • 2.注解:

      1. @JsonIgnore:排除属性。
      2. @JsonFormat:属性值得格式化
        @JsonFormat(pattern = “yyyy-MM-dd”)
    • 3.复杂java对象转换

      1. List:数组
      2. Map:对象格式一致

你可能感兴趣的:(Java,java,xml,json,xstream,gson)