JSON 数据格式

说明

学习 JSON 数据格式时整理的学习笔记。

目录

  • 说明
  • [1. JSON 简介](#1. JSON 简介)
    • [1.1 JSON 的发展经历](#1.1 JSON 的发展经历)
    • [1.2 JSON 标准规范](#1.2 JSON 标准规范)
      • [1.2.1 互联网标准](#1.2.1 互联网标准)
      • [1.2.2 国际技术标准](#1.2.2 国际技术标准)
  • [2. JSON 语法](#2. JSON 语法)
    • [2.1 基本规则](#2.1 基本规则)
    • [2.2 名称 - 值对](#2.2 名称 - 值对)
      • [2.2.1 名称字符串中的反斜杠](#2.2.1 名称字符串中的反斜杠)
      • [2.2.2 名称字符串中的双引号](#2.2.2 名称字符串中的双引号)
      • [2.2.3 名称字符串中的控制字符](#2.2.3 名称字符串中的控制字符)
      • [2.2.4 名称字符串中的 Unicode 转义字符](#2.2.4 名称字符串中的 Unicode 转义字符)
    • [2.3 JSON 的六个结构字符](#2.3 JSON 的六个结构字符)
    • [2.4 JSON 注释](#2.4 JSON 注释)
    • [2.5 JSON 格式化](#2.5 JSON 格式化)
    • [2.6 JSON 语法验证](#2.6 JSON 语法验证)
  • [3. JSON 数据类型](#3. JSON 数据类型)
    • [3.1 对象类型(object)](#3.1 对象类型(object))
    • [3.2 字符串类型(string)](#3.2 字符串类型(string))
    • [3.3 数字类型(number/integer)](#3.3 数字类型(number/integer))
    • [3.4 布尔类型(boolean)](#3.4 布尔类型(boolean))
    • [3.5 null 类型(null)](#3.5 null 类型(null))
    • [3.6 数组类型(array)](#3.6 数组类型(array))
  • [4. JSON Schema 模式校验](#4. JSON Schema 模式校验)
    • [4.1 JSON Schema 规范](#4.1 JSON Schema 规范)
    • [4.2 JSON Schema 使用示例](#4.2 JSON Schema 使用示例)
    • [4.3 JSON Schema 工具网站](#4.3 JSON Schema 工具网站)
  • 参考资料

1. JSON 简介

JSON(JavaScript Object Notation,JavaScript 对象表示法)起源于 JavaScript 语言,是一种轻量级的数据交换格式。 它由键值对组成,采用完全独立于编程语言的文本格式,易于人阅读和编写,同时也易于机器解析和生成,常用于前后端之间的数据交换 以及配置信息的存储NoSQL 数据库的数据存储

1.1 JSON 的发展经历

  • 1999年,道格拉斯·克罗克福德(Douglas Crockford)敏锐地意识到,JavaScript 中定义对象的字面量语法可以作为一种优秀的数据串行化格式,这个语法定义来源于标准 Standard ECMA-262 3rd Edition - December 1999。
  • 2001年,道格拉斯·克罗克福德首次在 https://www.json.org 上正式说明和推广这种格式,并将其命名为 JSON。
  • 2002-2005年,在 Web 开发社区中,人们发现,使用 JSON 作为数据交换格式,可以避免 Ajax(Asynchronous JavaScript and XML)技术中复杂的 XML 解析,JSON 逐渐取代 XML 成为 Web 应用程序数据交换的主流格式。
  • 2006年7月,IETF(Internet Engineering Task Force,互联网工程任务组)发布 JSON 的第一个官方互联网标准 RFC4627 ,道格拉斯·克罗克福德是主要作者,该标准将 JSON 的 MIME 类型定义为 application/json
  • 2013年10月,ECMA International(European Computer Manufacturers Association,欧洲计算机制造商协会)发布 JSON 的第一个国际技术标准 ECMA-404,这是一个简洁的、仅描述语法的标准,不涉及具体编码或解析行为,强调了 JSON 的语言无关性。
  • 2014年3月,IETF 依次发布 RFC7158 和 RFC7159,更新了 RFC4627,指出 JSON 文本的最顶层可以是任何 JSON 值(而不仅仅是对象或数组)。
  • 2017年12月,IETF 发布 RFC8259,这是当前最新的官方标准,指出 JSON 文本必须强制性使用 UTF-8 编码,消除之前的编码歧义,确保绝对的互操作性。同月,ECMA International 发布第二版 ECMA-404,澄清术语与措辞,对齐 RFC8259 标准。

1.2 JSON 标准规范

JSON 有两个标准规范,分别是由 IETF 发布的 JSON 互联网标准、由 ECMA International 发布的 JSON 国际技术标准,两者在语法规则上完全一致,开发者无需区分两者,实际应用中遵循任一标准均可。

1.2.1 互联网标准

由 IETF(Internet Engineering Task Force,互联网工程任务组)发布,是互联网标准文档,注重 JSON 在互联网传输中的应用,常用于互联网协议(如 HTTP API),历次标准如下:

1.2.2 国际技术标准

由 ECMA International(European Computer Manufacturers Association,欧洲计算机制造商协会)发布,是国际技术标准,内容更为简洁,仅描述 JSON 的语法定义和合法性规则,不涉及具体实现方式,常作为基础规范被编程语言和工具引用,历次标准如下:

2. JSON 语法

2.1 基本规则

  • JSON 文本必须是 UTF-8 编码。源于 RFC8259 标准规定,ECMA-404 标准虽未强制规定编码方式,但实际实现通常遵循 RFC8259 的 UTF-8 要求。
  • JSON 文本的顶层元素可以是对象数组。虽然 RFC7158 及其后续标准指出 JSON 文本的最顶层可以是任何 JSON 值(而不仅仅是对象或数组),实际应用中不满足这个条件时可能会报错。
  • JSON 文本的名称 - 值对中的值必需是以下六种基本数据类型之一。
    • 对象 (用 {} 包裹):名称 - 值对的无序集合
    • 数组 (用 [] 包裹):值的有序集合
    • 字符串 (用 "" 包裹):文本数据。
    • 数字:支持整数、小数、科学记数法。
    • 布尔值:true 或 false。
    • null:表示空值。

2.2 名称 - 值对

JSON 名称 - 值对是 JSON 中最基本的结构之一,它表示了一个名称和对应的值之间的关系,如下所示:

json 复制代码
"key": value
  • 其中 "key" 就是名称,是一个字符串,必需用英文双引号 " 括起来。
  • 其中 value 就是值,值必需是对象、字符串、数字、布尔值、null 和数组这六种数据类型之一,当且仅当值是字符串类型时需要用英文双引号括起来。
  • 必需使用英文冒号 : 来分隔名称和值,名称始终在左侧,值始终在右侧。

名称字符串可以是任何有效的字符串 ,以下字符串在 JSON 中作为名称都是合法的,但为了获得最大可移植性,应尽可能避免使用空格和特殊字符,最好仅使用英文字母 A~Z 或 a~z。

复制代码
"MyAnimal"
"My Animal"
" My Animal "
"+-*/!@#$%^&,()=_[]MyAnimal"
"Lindsay'sAnimal"
"李华"

下面例举名称字符串中出现反斜杠、双引号、控制字符、Unicode 转义字符这些典型特殊字符的例子,实际应用时不推荐这样做。

2.2.1 名称字符串中的反斜杠

名称字符串中无法单独使用反斜杠 \,需搭配转义字符 \ 使用,以下使用是合法的:

json 复制代码
"My\\Atimal"

2.2.2 名称字符串中的双引号

名称字符串中无法单独使用英文双引号 ",需搭配转义字符 \ 使用,以下使用是合法的:

json 复制代码
"My\"Atimal"

2.2.3 名称字符串中的控制字符

名称字符串中出现 \t\r\n\f\b 等控制字符是合法的,以下使用是合法的:

json 复制代码
"My\tAtimal"
"My\rAtimal"
"My\nAtimal"
"My\fAtimal"
"My\bAtimal"

2.2.4 名称字符串中的 Unicode 转义字符

名称字符串中出现 \uXXXX(四位十六进制表示)Unicode 转义字符是合法的,以下使用是合法的:

复制代码
"MyAtimal\u263A"

2.3 JSON 的六个结构字符

以下六个结构字符在不作为字符串组成部分时告诉机器如何读取数据,这六个结构字符之前或之后可以使用空格、缩进、换行符等空白字符而不影响 JSON 语义:

  • { 左花括号表示"开始读取对象";
  • } 右花括号表示"结束读取对象";
  • [ 左方括号表示"开始读取数组";
  • ] 右方括号表示"结束读取数组";
  • : 英文冒号表示"在名称 - 值对中分隔名称和值";
  • , 英文逗号表示"分隔对象中的名称 - 值对"或者"分隔数组中的值",表示"一个新部分的开始"。

2.4 JSON 注释

JSON 不支持添加注释。

2.5 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 复制代码
{
  "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": "晴"
}

2.6 JSON 语法验证

JSON 语法验证用于检测 JSON 语法是否正确:是否被花括号包裹,名称 - 值对是否以英文逗号分隔,名称和值之间是否以英文冒号分隔,左右括号是否成对匹配,等等。网上有很多在线的 JSON 语法验证工具,提供以下几个示例网站,可自行搜索。

3. JSON 数据类型

JSON 中的数据类型包括:对象类型(object)、字符串类型(string)、数字类型(number)、布尔类型(boolean)、null 类型(null)、数组类型(array)这六种。

3.1 对象类型(object)

JSON 对象是名称 - 值对的无序集合,语法如下:

  • JSON 对象由 {} 包裹。
  • 由 \(\geq0\) 个名称 - 值对组成。
  • 名称 - 值对之间用英文逗号 , 分隔。
  • 同一对象中名称可以重复,但不推荐这么做,标准 ECMA-404 和 RFC8259 明确写了名称不要求唯一,但是不同程序对重复名称的处理方式不同。

示例:

json 复制代码
{
  "name": "Alice",
  "age": 25,
  "isStudent": false,
  "hobbies": ["reading", "traveling"]
}

3.2 字符串类型(string)

JSON 中的字符串可以由任何 Unicode 字符构成,字符串的两边必须被英文双引号 包裹。以下字符需搭配转义字符 \ 使用才能表达其自身含义:

  • " 英文双引号,需写为 \",否则不合语法。
  • \ 反斜杠,需写为 \\,否则不合语法。
  • / 正斜杠,需写为 \/,否则实际效果可能和预期不一致,与编程语言以及具体实现有关。
  • \b 退格符,需写为 \\b,否则实际效果可能和预期不一致,与编程语言以及具体实现有关。
  • \f 换页符,需写为 \\f,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。
  • \n 换行符,需写为 \\n,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。
  • \r 回车符,需写为 \\r,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。
  • \t 制表符,需写为 \\t,否则 实际效果可能和预期不一致,与编程语言以及具体实现有关。
  • \uXXXX(四位十六进制表示)Unicode 转义字符,需写为 \\uXXXX,否则实际效果可能和预期不一致,与编程语言以及具体实现有关。

示例,下面字符串类型数据都是合法的,但产生的实际效果可能不同:

json 复制代码
{
  "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 字面值,无笑脸字符。

3.3 数字类型(number/integer)

JSON 中的数字可以是整数、小数或者指数,不支持 NaNInfinity 等特殊数值字面量。

  • integer 类型:整数。
  • number 类型:整数、小数或者指数。

示例:

json 复制代码
{
  "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 无穷大。

3.4 布尔类型(boolean)

JSON 中的布尔值只能是 truefalse,严格小写,任何其他形式的写法都不合语法。示例:

json 复制代码
{
  "isActive": true,
  "isDeleted": false
}

3.5 null 类型(null)

JSON 中 null 是一个表示没有值(空值)的值,严格小写,任何其他形式的写法都不合语法。示例:

json 复制代码
{
  "optionalField": null
}

3.6 数组类型(array)

JSON 数组是值的有序集合,语法如下:

  • JSON 数组由 [] 包裹。
  • 由 \(\geq0\) 个值组成。
  • 值之间用英文逗号 , 分隔。
  • 值必需是对象、字符串、数字、布尔值、null 和数组这六种数据类型之一。
  • 值可以是不同的数据类型,标准中未做约束,但为了获得最大可移植性,应尽量使用相同的数据类型。

示例:

json 复制代码
[
  "hello",
  42,
  true,
  null,
  {"name": "Alice"},
  [1, 2, 3]
]

4. JSON Schema 模式校验

JSON Schema 用来对 JSON 数据进行模式校验、数据一致性校验。前面提到的 JSON 语法验证只能用于检测 JSON 语法是否正确,而 JSON Schema 可以用来检验给定的 JSON 数据是否满足更具体的使用要求:

  • **是否包含所需要的数据?**可以规定哪些数据(名称 - 值对)是必需包含的,哪些数据是可选的。
  • **值的数据类型是否正确?**可以规定指定名称下值的数据类型。
  • **值的形式是否满足约束规则?**可以规定指定名称下值的取值范围、最小值、最大值等。

4.1 JSON Schema 规范

2007 年克里希普(Kris Zyp,Chris Zyp)提出 JSON Schema 用于 JSON 文本模式校验,2009年12月,JSON Schema 规范以 IETF 互联网草案 Draft 0Draft 1 的形式首次面世,但并未成为正式的 IETF 标准,随后的十余年间,JSON Schema 在社区的驱动下,经历了多个关键的发展阶段和领导团队。截至目前,JSON Schema 规范仍作为一个独立的由社区驱动的开源项目,任何人都可以参与讨论和贡献,尽管没有正式的管理组织,JSON Schema 早已是业界公认的事实标准。最新的稳定规范草案为 2020-12 版本,历次发布版本详见 JSON Schema - Specification Links。各规范的详细内容详见对应链接:

  • 2009年12月5日,发布 Draft 0
  • 2009年12月5日,发布 Draft 1,修复错误并取代当天发布的 Draft 0
  • 2010年3月23日,发布 Draft 2
  • 2010年11月22日,发布 Draft 3
  • 2013年1月31日,发布 Draft 4
  • 2016年10月13日,发布 Draft 5
  • 2017年4月21日,发布 Draft 6
  • 2018年3月19日,发布 Draft 7
  • 2019年9月17日,发布 Draft 2019-09,也称 Draft 8
  • 2022年6月16日,发布 Draft 2020-12,为当前最新规范。

4.2 JSON Schema 使用示例

使用 JSON Schema 进行模式校验时,通常分为以下三步:

  1. 定义 Schema:编写 JSON Schema,这是一个 JSON 对象,用于描述数据的期望结构。
  2. 验证数据 :使用验证库将 JSON 数据与 Schema 对比,检查是否符合约束,这一步与编程语言以及具体实现有关,C++ 开发者可以参考 从零吃透 JSON Schema 2020-12:C++ 开发者专属实战指南-CSDN博客
  3. 处理验证结果:如果验证失败,则返回验证失败的详细信息(缺失字段、类型错误等)。

一个简单的 JSON Schema 示例:

json 复制代码
{
  "$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 对象,表达含义如下:

  • 当前 Schema 语法遵循 Draft 2020-12 版本规范。
  • 顶层数据类型必需为对象类型(object)
  • 名称 name 下值的数据类型必需为字符串类型(string)
  • 名称 age 下值的数据类型必需为整数类型(integer),且值不小于 0,也就是非负整数。
  • 名称 email 下值的数据类型必需为字符串类型(string) ,且必需符合 email 格式。
  • 名称 nameemail 是必需包含的,不能省略。
  • 不允许包含 nameageemail 这三个名称之外的其他名称 - 值对。

验证成功的、符合此 Schema 的 JSON 数据示例一:

json 复制代码
{
  "name": "Alice",
  "age": 25,
  "email": "alice@example.com"
}

验证成功的、符合此 Schema 的 JSON 数据示例二:

json 复制代码
{
  "name": "Alice",
  "email": "alice@example.com"
}

验证失败的、不符合此 Schema 的示例一(age 值小于 0,email 值不符合 email 格式):

json 复制代码
{
  "name": "Bob",
  "age": -5,
  "email": "invalid-email"
}

验证失败的、不符合此 Schema 的示例二(包含了 nameageemail 这三个名称之外的名称 weight):

复制代码
{
  "name": "Alice",
  "age": 25,
  "email": "alice@example.com",
  "weight": 56
}

验证失败的、不符合此 Schema 的示例三(没有包含必需名称 email):

json 复制代码
{
  "name": "Alice"
}

4.3 JSON Schema 工具网站

提供以下几个 JSON Schema 工具网站:

参考资料

1\] 美 巴塞特 Bassett, Lindsay.JSON必知必会\[M\].人民邮电出版社,2016. \[2\] [Introducing JSON](https://www.json.org/json-en.html). \[3\] [JSON Schema (json-schema.org)](https://json-schema.org/). \[4\] [开发爱好者 - JSON 概述与历史](https://www.develop.fan/Static/course/detail?classId=55324914c3a549e0b585cc8fb6124190). \[5\] [JSON传奇:从偶然诞生到统治Web的数据交换之王 (zeeklog.com)](https://zeeklog.com/jsonchuan-qi-cong-ou-ran-dan-sheng-dao-tong-zhi-webde-shu-ju-jiao-huan-zhi-wang-2/). \[6\] [JSON的发展历史:从JavaScript到跨语言数据交换标准 - WeJSON博客](https://wejson.cn/blog/json-history.html). \[7\] [JSON标准及语法介绍 \| TT工作室 (snownight22.github.io)](https://snownight22.github.io/TTworksBlog/2025/02/28/json). \[8\] [JSON基础知识与实践:轻松理解并应用JSON格式-腾讯云开发者社区-腾讯云 (tencent.com)](https://cloud.tencent.com/developer/article/2545943). \[9\] [JSON 文本语法格式_json格式要求-CSDN博客](https://blog.csdn.net/m0_53605808/article/details/145168748). \[10\] [JSON允许Key重复吗? - 知乎 (zhihu.com)](https://www.zhihu.com/question/373213978). \[11\] [什么是 JSON Schema:描述和验证 JSON 数据结构与内容的标准规范-CSDN博客](https://blog.csdn.net/u013172930/article/details/148424445). \[12\] [从零吃透 JSON Schema 2020-12:C++ 开发者专属实战指南_json schema 规范(中文版) 2020-12-CSDN博客](https://blog.csdn.net/Small_entreprene/article/details/155096158).

相关推荐
漫谈网络10 个月前
YAML 数据格式详解
python·yml·yaml·数据格式
漫谈网络1 年前
JSON 数据格式详解
网络·python·json·数据格式
SuperherRo1 年前
基础入门-传输加密&数据格式&编码算法&密文存储&代码混淆&逆向保护&安全影响
数据格式·代码混淆·传输加密·密码存储
陈壮实的搬砖生活1 年前
深入理解Python中的常用数据格式(如csv、json、pickle、npz、h5等):存储机制与性能解析
python·数据格式
清风20222 年前
yolov5 json 和 txt数据格式关系
yolov5·数据格式
Amd7942 年前
探索多种数据格式:JSON、YAML、XML、CSV等数据格式详解与比较
xml·json·csv·yaml·数据交换·数据格式·格式比较
华为云开发者联盟2 年前
实例讲解Python 解析JSON实现主机管理
json·python json·数据格式·主机管理