Java笔记十九——XML与JSON

XML和JSON是两种经常在网络使用的数据表示格式

XML简介

XML有几个特点:一是纯文本,默认使用UTF-8编码,二是可嵌套,适合表示结构化数据。

XML的结构

XML有固定的结构,首行必定是<?xml version="1.0"?>,可以加上可选的编码。紧接着,如果以类似声明的是文档定义类型(DTD:Document Type Definition),DTD是可选的。接下来是XML的文档内容,一个XML文档有且仅有一个根元素,根元素可以包含任意个子元素,元素可以包含属性,例如,1234567包含一个属性lang=“CN”,且元素必须正确嵌套。如果是空元素,可以用表示。

由于使用了<、>以及引号等标识符,如果内容出现了特殊符号,需要使用&???;表示转义。
在这里插入图片描述
小结
XML使用嵌套结构的数据表示方式,支持格式验证;
XML常用于配置文件、网络消息传输等。

使用DOM

XML是一种树形结构的文档,它有两种标准的解析API:

  • DOM:一次性读取XML,并在内存中表示为树形结构;(树形结构处理XML结构)
  • SAX:以流的形式读取XML,使用事件回调。

对于DOM API解析出来的结构,我们从根节点Document出发,可以遍历所有子节点,获取所有元素、属性、文本数据,还可以包括注释,这些节点被统称为Node,每个Node都有自己的Type,根据Type来区分一个Node到底是元素,还是属性,还是文本,等等。
使用DOM API时,如果要读取某个元素的文本,需要访问它的Text类型的子节点,所以使用起来还是比较繁琐的。
在这里插入图片描述

在这里插入图片描述

使用SAX

SAX——基于流的解析方式,边读取XML边解析(占用数据小),以事件回调的方式让调用者获取数据
在这里插入图片描述
使用SAX API解析XML,Java代码如下

InputStream input = Main.class.getResourceAsStream("/book.xml");
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(input, new MyHandler());

关键代码SAXParser.parse()除了需要传入一个InputStream外,还需要传入一个回调对象,这个对象要继承自DefaultHandler:

class MyHandler extends DefaultHandler {
    public void startDocument() throws SAXException {
        print("start document");
    }

    public void endDocument() throws SAXException {
        print("end document");
    }

    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        print("start element:", localName, qName);
    }

    public void endElement(String uri, String localName, String qName) throws SAXException {
        print("end element:", localName, qName);
    }

    public void characters(char[] ch, int start, int length) throws SAXException {
        print("characters:", new String(ch, start, length));
    }

    public void error(SAXParseException e) throws SAXException {
        print("error:", e);
    }

    void print(Object... objs) {
        for (Object obj : objs) {
            System.out.print(obj);
            System.out.print(" ");
        }
        System.out.println();
    }
}

使用Jackson

在这里插入图片描述

XML解析成一个JavaBean:使用Jackson这个开源第三方库
使用Jackson,先添加两个Maven的依赖:

  • com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.10.1
  • org.codehaus.woodstox:woodstox-core-asl:4.4.1
    然后,定义好JavaBean,就可以用下面几行代码解析:
InputStream input = Main.class.getResourceAsStream("/book.xml");
JacksonXmlModule module = new JacksonXmlModule();
XmlMapper mapper = new XmlMapper(module);//XmlMapper就是核心对象
Book book = mapper.readValue(input, Book.class);//用readValue(InputStream, Class)直接读取XML并返回一个JavaBean
System.out.println(book.id);
System.out.println(book.name);
System.out.println(book.author);
System.out.println(book.isbn);
System.out.println(book.tags);
System.out.println(book.pubDate);

使用JSON

XML这种数据结构的特点是功能全面,但标签繁琐,格式复杂。在Web上使用XML现在越来越少,取而代之的是JSON这种数据结构。一个典型的JSON如下:
在这里插入图片描述
JSON作为数据传输的格式,有几个显著特点:

  • JSON只允许使用UTF-8编码,不存在编码问题;
  • JSON只允许使用双引号作为key,特殊字符用\转义,格式简单;
  • 浏览器内置JSON支持,如果把数据用JSON发送给浏览器,可以用JavaScript直接处理。

JSON适合表示层次结构,因为它格式简单,仅支持以下几种数据类型:
键值对:{“key”: value}
数组:[1, 2, 3]
字符串:“abc”
数值(整数和浮点数):12.34
布尔值:true或false
空值:null
浏览器直接支持使用JavaScript对JSON进行读写:

// JSON string to JavaScript object:
jsObj = JSON.parse(jsonStr);

// JavaScript object to JSON string:
jsonStr = JSON.stringify(jsObj);

开发Web应用的时候,使用JSON作为数据传输,在浏览器端非常方便。
常用的用于解析JSON的第三方库有:Jackson、Gson、Fastjson等

Jackson也可以解析JSON!只需要引入以下Maven依赖:
com.fasterxml.jackson.core:jackson-databind:2.10.0
就可以使用下面的代码解析一个JSON文件:

InputStream input = Main.class.getResourceAsStream("/book.json");
ObjectMapper mapper = new ObjectMapper();//核心代码是创建一个ObjectMapper对象
// 反序列化时忽略不存在的JavaBean属性:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//解析时如果JavaBean不存在该属性时解析不会报错
Book book = mapper.readValue(input, Book.class);

把JSON解析为JavaBean的过程称为反序列化。如果把JavaBean变为JSON,那就是序列化。要实现JavaBean到JSON的序列化,只需要一行代码:

String json = mapper.writeValueAsString(book); 

要把JSON的某些值解析为特定的Java对象,例如LocalDate,也是完全可以的。例如:

{
“name”: “Java核心技术”,
“pubDate”: “2016-09-01”
}
要解析为:

public class Book {
    public String name;
    public LocalDate pubDate;
}

只需要引入标准的JSR 310关于JavaTime的数据格式定义至Maven:
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.0
然后,在创建ObjectMapper时,注册一个新的JavaTimeModule:
ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());
有些时候,内置的解析规则和扩展的解析规则如果都不满足我们的需求,还可以自定义解析。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值