























学习 JSON 数据格式时整理的学习笔记。
JSON(JavaScript Object Notation,JavaScript 对象表示法)起源于 JavaScript 语言,是一种轻量级的数据交换格式。 它由键值对组成,采用完全独立于编程语言的文本格式,易于人阅读和编写,同时也易于机器解析和生成,常用于前后端之间的数据交换以及配置信息的存储、NoSQL 数据库的数据存储。
application/json。JSON 有两个标准规范,分别是由 IETF 发布的 JSON 互联网标准、由 ECMA International 发布的 JSON 国际技术标准,两者在语法规则上完全一致,开发者无需区分两者,实际应用中遵循任一标准均可。
由 IETF(Internet Engineering Task Force,互联网工程任务组)发布,是互联网标准文档,注重 JSON 在互联网传输中的应用,常用于互联网协议(如 HTTP API),历次标准如下:
由 ECMA International(European Computer Manufacturers Association,欧洲计算机制造商协会)发布,是国际技术标准,内容更为简洁,仅描述 JSON 的语法定义和合法性规则,不涉及具体实现方式,常作为基础规范被编程语言和工具引用,历次标准如下:
{} 包裹):名称 - 值对的无序集合。[] 包裹):值的有序集合。"" 包裹):文本数据。JSON 名称 - 值对是 JSON 中最基本的结构之一,它表示了一个名称和对应的值之间的关系,如下所示:
"key": value
"key" 就是名称,是一个字符串,必需用英文双引号 " 括起来。value 就是值,值必需是对象、字符串、数字、布尔值、null 和数组这六种数据类型之一,当且仅当值是字符串类型时需要用英文双引号括起来。: 来分隔名称和值,名称始终在左侧,值始终在右侧。名称字符串可以是任何有效的字符串,以下字符串在 JSON 中作为名称都是合法的,但为了获得最大可移植性,应尽可能避免使用空格和特殊字符,最好仅使用英文字母 A~Z 或 a~z。
"MyAnimal"
"My Animal"
" My Animal "
"+-*/!@#$%^&,()=_[]MyAnimal"
"Lindsay'sAnimal"
"李华"
下面例举名称字符串中出现反斜杠、双引号、控制字符、Unicode 转义字符这些典型特殊字符的例子,实际应用时不推荐这样做。
名称字符串中无法单独使用反斜杠 \,需搭配转义字符 \ 使用,以下使用是合法的:
"My\\Atimal"
名称字符串中无法单独使用英文双引号 ",需搭配转义字符 \ 使用,以下使用是合法的:
"My\"Atimal"
名称字符串中出现 \t、\r、\n、\f、\b 等控制字符是合法的,以下使用是合法的:
"My\tAtimal"
"My\rAtimal"
"My\nAtimal"
"My\fAtimal"
"My\bAtimal"
名称字符串中出现 \uXXXX(四位十六进制表示)Unicode 转义字符是合法的,以下使用是合法的:
"MyAtimal\u263A"
以下六个结构字符在不作为字符串组成部分时告诉机器如何读取数据,这六个结构字符之前或之后可以使用空格、缩进、换行符等空白字符而不影响 JSON 语义:
{ 左花括号表示“开始读取对象”;} 右花括号表示“结束读取对象”;[ 左方括号表示“开始读取数组”;] 右方括号表示“结束读取数组”;: 英文冒号表示“在名称 - 值对中分隔名称和值”;, 英文逗号表示“分隔对象中的名称 - 值对”或者“分隔数组中的值”,表示“一个新部分的开始”。JSON 不支持添加注释。
计算机生成的 JSON 数据通常是不易于人直接阅读的,如下所示,这种紧凑的格式去除了多余的空格、缩进和换行符,使得数据体积更小,传输时占用更少的带宽、存储时占用更小的容量。
{"date":"22","ymd":"2018-09-22","week":"星期六","sunrise":"05:57","high":"高温 26.0℃","low":"低温 15.0℃","sunset":"18:10","aqi":55,"fx":"西北风","fl":"4-5级","type":"晴"}
JSON 格式化是指将 JSON 数据按照一定的格式排列,适当添加空格、缩进和换行符,使其更易于人阅读和理解,如下是对上述 JSON 数据格式化的结果。
{
"date": "22",
"ymd": "2018-09-22",
"week": "星期六",
"sunrise": "05:57",
"high": "高温 26.0℃",
"low": "低温 15.0℃",
"sunset": "18:10",
"aqi": 55,
"fx": "西北风",
"fl": "4-5级",
"type": "晴"
}
JSON 语法验证用于检测 JSON 语法是否正确:是否被花括号包裹,名称 - 值对是否以英文逗号分隔,名称和值之间是否以英文冒号分隔,左右括号是否成对匹配,等等。网上有很多在线的 JSON 语法验证工具,提供以下几个示例网站,可自行搜索。
JSON 中的数据类型包括:对象类型(object)、字符串类型(string)、数字类型(number)、布尔类型(boolean)、null 类型(null)、数组类型(array)这六种。
JSON 对象是名称 - 值对的无序集合,语法如下:
{} 包裹。, 分隔。示例:
{
"name": "Alice",
"age": 25,
"isStudent": false,
"hobbies": ["reading", "traveling"]
}
JSON 中的字符串可以由任何 Unicode 字符构成,字符串的两边必须被英文双引号包裹。以下字符需搭配转义字符 \ 使用才能表达其自身含义:
" 英文双引号,需写为 \",否则不合语法。\ 反斜杠,需写为 \\,否则不合语法。/ 正斜杠,需写为 \/,否则实际效果可能和预期不一致,与编程语言以及具体实现有关。\b 退格符,需写为 \\b,否则实际效果可能和预期不一致,与编程语言以及具体实现有关。\f 换页符,需写为 \\f,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。\n 换行符,需写为 \\n,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。\r 回车符,需写为 \\r,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。\t 制表符,需写为 \\t,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。\uXXXX(四位十六进制表示)Unicode 转义字符,需写为 \\uXXXX,否则实际效果可能和预期不一致,与编程语言以及具体实现有关。示例,下面字符串类型数据都是合法的,但产生的实际效果可能不同:
{
"saying": "Einstein once said, \"Imagination is more important than knowledge.\"",
"dataPath": "E:\\NoteBook",
"equationA": "10/5=2",
"equationB": "10\/5=2",
"storyA": "\t Once upon a time\b\f\r, in a far away land \n there lived a princess.\u263A",
"storyB": "\\t Once upon a time\\b\\f\\r, in a far away land \\n there lived a princess.\\u263A"
}
在 MATLAB 中使用 jsondecode() 搭配 fileread() 进行测试,结果如下:
正斜杠 / 写为 / 或者 \/ 时,两种写法解析出来的字符串是相同的,具体为字符串打印效果相同、字符串长度相同、字符串各字符对应相同。
退格符 \b 写为 \b 或者 \\b 时,两种写法效果不同:
\b 时,字符长度计数为 1,打印时产生退格效果,后一字符会替代前一字符;\\b 时,字符长度计数为 2,打印时显示 \b 字面值,无退格效果。换页符 \f 写为 \f 或者 \\f 时,两种写法效果不同:
\f 时,字符长度计数为 1,打印时显示带阴影的 FF 单字符;\\f 时,字符长度计数为 2,打印时显示 \f 字面值,无其他效果。换行符 \n 写为 \n 或者 \\n 时,两种写法效果不同:
\n 时,字符长度计数为 1,打印时产生换行效果;\\n 时,字符长度计数为 2,打印时显示 \n 字面值,无换行效果。回车符 \r 写为 \r 或者 \\r 时,两种写法效果不同:
\r 时,字符长度计数为 1,打印时产生换行效果;\\r 时,字符长度计数为 2,打印时显示 \r 字面值,无换行效果。制表符 \t 写为 \t 或者 \\t 时,两种写法效果不同:
\t 时,字符长度计数为 1,打印时产生缩进效果;\\t 时,字符长度计数为 2,打印时显示 \t 字面值,无缩进效果。Unicode 转义字符 \u263A 写为 \u263A 或者 \\u263A 时,两种写法效果不同:
\u263A 时,字符长度计数为 1,打印时产生笑脸字符;\\u263A 时,字符长度计数为 6,打印时显示 \u263A 字面值,无笑脸字符。JSON 中的数字可以是整数、小数或者指数,不支持 NaN、Infinity 等特殊数值字面量。
integer 类型:整数。number 类型:整数、小数或者指数。示例:
{
"integer": 42,
"negative": -42,
"float": 3.14159,
"double": 3.141592653589793,
"scientificA": 6.022e+23,
"scientificB": 6.022E+23
}
由于计算机使用 IEEE754 标准存储浮点数,该标准以有限位数的二进制形式近似表示十进制数值,导致超范围的数值和某些十进制小数无法精确存储,数字文本与数值相互转换的过程中可能会产生误差丢失精度。示例:
3.141592653589793238462643383279 有效位数过多,解析为 double 时只能存储 3.141592653589793 共 16 位有效位数,后续小数会丢失。1E400 数值过大,超过 double 能表示的范围(约 \(-1.79E+308\) 至 \(+1.79E+308\)),可能无法正确解析,在 MATLAB 中会被解析为 Inf 无穷大。JSON 中的布尔值只能是 true 或 false,严格小写,任何其他形式的写法都不合语法。示例:
{
"isActive": true,
"isDeleted": false
}
JSON 中 null 是一个表示没有值(空值)的值,严格小写,任何其他形式的写法都不合语法。示例:
{
"optionalField": null
}
JSON 数组是值的有序集合,语法如下:
[] 包裹。, 分隔。示例:
[
"hello",
42,
true,
null,
{"name": "Alice"},
[1, 2, 3]
]
JSON Schema 用来对 JSON 数据进行模式校验、数据一致性校验。前面提到的 JSON 语法验证只能用于检测 JSON 语法是否正确,而 JSON Schema 可以用来检验给定的 JSON 数据是否满足更具体的使用要求:
2007 年克里希普(Kris Zyp,Chris Zyp)提出 JSON Schema 用于 JSON 文本模式校验,2009年12月,JSON Schema 规范以 IETF 互联网草案 Draft 0 和 Draft 1 的形式首次面世,但并未成为正式的 IETF 标准,随后的十余年间,JSON Schema 在社区的驱动下,经历了多个关键的发展阶段和领导团队。截至目前,JSON Schema 规范仍作为一个独立的由社区驱动的开源项目,任何人都可以参与讨论和贡献,尽管没有正式的管理组织,JSON Schema 早已是业界公认的事实标准。最新的稳定规范草案为 2020-12 版本,历次发布版本详见 JSON Schema - Specification Links。各规范的详细内容详见对应链接:
使用 JSON Schema 进行模式校验时,通常分为以下三步:
一个简单的 JSON Schema 示例:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer", "minimum": 0 },
"email": { "type": "string", "format": "email" }
},
"required": ["name", "email"],
"additionalProperties": false
}
此 Schema 描述一个 JSON 对象,表达含义如下:
name 下值的数据类型必需为字符串类型(string)。age 下值的数据类型必需为整数类型(integer),且值不小于 0,也就是非负整数。email 下值的数据类型必需为字符串类型(string),且必需符合 email 格式。name 和 email 是必需包含的,不能省略。name、age、email 这三个名称之外的其他名称 - 值对。验证成功的、符合此 Schema 的 JSON 数据示例一:
{
"name": "Alice",
"age": 25,
"email": "alice@example.com"
}
验证成功的、符合此 Schema 的 JSON 数据示例二:
{
"name": "Alice",
"email": "alice@example.com"
}
验证失败的、不符合此 Schema 的示例一(age 值小于 0,email 值不符合 email 格式):
{
"name": "Bob",
"age": -5,
"email": "invalid-email"
}
验证失败的、不符合此 Schema 的示例二(包含了 name、age、email 这三个名称之外的名称 weight):
{
"name": "Alice",
"age": 25,
"email": "alice@example.com",
"weight": 56
}
验证失败的、不符合此 Schema 的示例三(没有包含必需名称 email):
{
"name": "Alice"
}
提供以下几个 JSON Schema 工具网站:
[1] 美 巴塞特 Bassett, Lindsay.JSON必知必会[M].人民邮电出版社,2016.
[2] Introducing JSON.
[3] JSON Schema (json-schema.org).
[4] 开发爱好者 - JSON 概述与历史.
[5] JSON传奇:从偶然诞生到统治Web的数据交换之王 (zeeklog.com).
[6] JSON的发展历史:从JavaScript到跨语言数据交换标准 - WeJSON博客.
[7] JSON标准及语法介绍 | TT工作室 (snownight22.github.io).
[8] JSON基础知识与实践:轻松理解并应用JSON格式-腾讯云开发者社区-腾讯云 (tencent.com).
[9] JSON 文本语法格式_json格式要求-CSDN博客.
[10] JSON允许Key重复吗? - 知乎 (zhihu.com).
[11] 什么是 JSON Schema:描述和验证 JSON 数据结构与内容的标准规范-CSDN博客.
[12] 从零吃透 JSON Schema 2020-12:C++ 开发者专属实战指南_json schema 规范(中文版) 2020-12-CSDN博客.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。