文本数据存储语言
大约 13 分钟
文本数据存储语言
YAML
基本介绍
- YAML 可用于表示清单, 列表等数据形态, 通常用于表达数据结构与配置文件
- YAML 文件使用后缀
.yml
- YAML 的基本语法如下
- 对大小写敏感
- 使用缩进表示层级, 缩进只能使用空格, 但数量无限制 (同一层级缩进相同)
- 使用
#
用于注释内容的开始
- YAML 支持数据类型
- 纯量, 即单个不可分的值
- 数组 (列表)
- 对象 (键值对)
纯量表示
YAML 支持以下类型的纯量
布尔值
- 真值表示:
TRUE
,True
,true
- 假值表示:
FALSE
,False
,false
整数 (任何进制中均允许使用单个 _
作为分隔, 可有任意个分隔符)
- 十进制表示
114
- 二进制表示
0b0111_0010
- 八进制表示
0162
- 十六进制表示 (大小写均可)
0x72
浮点数
- 一般表示
+3.14
- 科学计数法表示
3.14e+5
字符串
- 直接表示 (内容无法解析时视为字符串)
Hello World
- 使用
'
或"
包裹 (推荐, 防止其中字符被解析)"Hello World"
'
包裹时, 不会对包裹内容进行转义"
包裹时, 可使用\
作为转义符, 如\n
表示换行
- 允许多行字符串 (无论是否使用
'
包裹)- 各行字符串在文件中的起始位置必须与第一行对齐
- 单个换行表示空格, 两个换行 (空行) 表示换行符
空 (对于基本加载器不支持, 将直接解析为字符串)
- 使用符号表示
~
- 使用关键字表示
Null
,null
,NULL
- 没有输入内容
日期与时间
- 仅日期表示
yyyy-MM-dd
, 例如2024-4-3
- 日期与时间表示
yyyy-MM-ddTHH:mm:ss
, 其中T
为分隔符
复合结构
- 一个 YAML 文件只能表示一个值, 因此通常以列表或对象作为基础
列表表示
- 在同一层级中使用多行
- <value>
表示列表中的元素- 值
value
可以是任意支持类型 - 对于复合结构, 一般在
-
后加一个换行, 并在下一层级中定义
- 值
- 使用单行
[value1, value2, ...]
表示列表
对象表示
- 在同一层级中使用多行
<key>: <value>
的键值对表示对象 - 使用单行
{key1: value1, key2: value2}
表示对象 (注意此处:
依然有要求)
TOML
基本介绍
- TOML 是一种专门用于表示配置文件的格式, 相比 YAML 更加稳定
- TOML 文件使用后缀
.toml
- TOML 的基本语法如下
- 对大小写敏感, 且文档必须是 UTF-8 编码
- 表示数据时, 将
与制表符视为空白, 其余均为需要解析的符号
- 使用
#
用于注释内容的开始
- TOML 支持数据类型
- 对象 (TOML 中称为表)
- 数组
- 纯量
纯量表示
字符串 (TOML 中共有四种字符串)
- 基本字符串, 使用
"
包裹, 仅能有单行- 基本字符串内可使用
\
用于转义, 常用的如下 \t
制表符\n
换行\"
引号\\
反斜杠\uXXXX
unicode 字符
- 基本字符串内可使用
- 多行字符串, 使用
"""
包裹- 多行字符串将包含换行符
- 在单行文本末尾使用
\
, 将忽略之后的换行与空格, 与最先出现的文本连接 - 当文本末尾换行使用
"""
, 将导致文本末尾被加上一个换行, 此时可使用\
或让结尾的"""
紧跟文本末尾 - 多行字符串同样可以使用
\
转义, 同基本字符串
- 字面字符串, 使用
'
包裹, 仅能有单行- 子面字符串不允许转义, 可用于表示正则表达式, Windows 路径等出现大量
\
的情况 - 类似的还有多行字面字符串
'''
, 多行字面字符串中允许出现单个'
- 子面字符串不允许转义, 可用于表示正则表达式, Windows 路径等出现大量
数值
- 数值的基本表示与 YAML 的数值类似, 此处省略
- 此外还能使用
inf
表示无穷,nan
表示非数值
其他纯量
- 布尔值使用
true
表示真,false
表示假 - 时间与 YAML 的时间类似, 此处省略
复合结构
整个 TOML 文件本身即一个对象, 即使是最底层的值都需要通过键值对的方式表示
键值对表示
- 通过
=
连接键名与键值, 通常等号两侧有空格, 一个键值对只能在一行内定义 - 裸键即基本键名, 只能使用字母, 数组, 下划线与短横
-
- 引号键即通过
"
包含的键名, 可表示任意键名, 但并不推荐 - 可使用
.
连接不同键名 (裸键或引号键), 例如A."B"
表明键A
的值为一个对象, 该对象下有键"B"
- 同一个对象中不允许出现两个同名的键
对象 (表)
- 最基本的方法即使用
.
连接键名, 以表示特定对象键值下的键值对 - 推荐通过单行的
[]
包裹的键名 (可以是任意一种键名) 为表头, 之后直到一个新的表头出现, 下方的内容都将作为该键名下对象的键值对- 在文本上, 该方法体现为特定部分的设置
- 在数据上, 该方法体现为定义对象键值
- 注意, 同一个键名只能以
[]
包裹的方式出现一次, 其中[A.B], [A.C]
视为两个键名
- 此外还可以使用内联的方式表示对象, 此时对象的键值对使用
{}
包裹, 键值对之间使用,
分隔, 内联表示时不允许换行
数组
- 基本数组即内联数组, 数组整体使用
[]
包裹, 数组元素之间使用,
分隔且数组允许跨行, 也可以使用内联表, 嵌套数组, 一般纯量作为元素 - 对于以对象为元素的数组还可使用单行的
[[]]
包裹键名, 此时将表示数组中的一个元素, 每个相同键名的[[]]
结构都将表示数组中的下一个元素
文件示例
# 全局设置
title = "Default Figure Style"
figure_size = [640, 480] # 表示 .figure_size
[plot] # 关于 plot 的设置
projection = "normal" # 表示 .plot.projection
size = [600, 400]
[plot.legend] # 关于 plot 中的 legend 的设置
position = [500, 300] # 表示 .plot.legend.position
legends = ["line A", "line B"]
[plot.lims]
xlim = [-10, 10]
ylim = [0, 10]
JSON
基本介绍
- JSON 本质为 Javascript 对象表示法, 可用于存储和交换文本信息, 读写速度较快
- JSON 文件使用后缀
.json
- JSON 的基本语法如下
- 对大小写敏感
- 对层级与缩进没有要求, 但一般会使用缩进增加可读性
- 通常不允许注释
- JSON 支持数据类型
- JSON 值, 即单个不可分的值
- 数组 (列表)
- 对象 (键值对)
JSON 值
JSON 支持以下纯量
- 布尔值
- 使用关键字
ture
表示真值 - 使用关键字
false
表示假值
- 使用关键字
- 数字
- 支持浮点数与整数, 但仅能使用十进制
- 允许使用
e
或E
使用科学计数法表示数值
- 字符串
- 字符串只能使用双引号
"
包裹 - 字符串内不允许有换行, 只能在单行内表示自负床
- 使用
\
作为转义符, 常用的有\n
换行,\t
制表符\u + XXXX
unicode 字符,XXXX
为四位十六进制数\", \\
符号转义
- 字符串只能使用双引号
- 空
- 使用关键字
null
表示空
- 使用关键字
复合结构
- 允许在表示复合结构时, 在结构符号之间插入任意的换行与空格
- 一个 JSON 文件只能表示一个值, 因此通常以列表或对象作为基础
- 列表表示
- 使用
[]
包裹列表,,
分隔各个元素 - 例如
[value1, value2, ...]
- 使用
- 对象表示
- 使用
{}
包裹对象,:
分隔键与值,,
分隔各个键值对 - 允许以任意 JSON 值作为键, 但是一个对象中不能有重复的键
- 例如
{key1: value1, ...}
- 使用
JSON 模板
参考 https://json-schema.org/learn/getting-started-step-by-step
由于 JSON 一般用于表示具有特定结构的数据或对象, 因此可使用模板对数据的格式进行规范, 模板同样为一个 JSON 文件, 一般使用后缀 .schema.json
使用时, 在根对象中添加键 $schema
并以模板文件的路径为值, 可以是网络路径或本地路径
以下仅介绍部分模板编写, 具体见官方文档
模板描述
模板文件以对象为基础数据, 并且包含了以下必须的键
$schema
模板标准, 一般为以下字符串https://json-schema.org/draft/2020-12/schema
https://json-schema.org/draft-07/schema#
$id
模板访问路径
对于本地模板使用本地的路径, 如果模板存放在网上则可使用链接title
模板标题, 字符串description
基础数据介绍type
文件基础数据类型, 字符串- 具体介绍见后, 一般为
object
, 即以对象为 JSON 文件的基础数据
- 具体介绍见后, 一般为
- 用于描述基础数据的键同样位于该基础数据中
值模板
对于任意值的模板, 均使用一个对象表示, 且至少有以下键
type
值的类型标识, 没有时为任意类型description
对于值的描述- 剩余的键用于表示值的约束等信息, 一般均为可选键
数值
- 类型标识
- 对于整数有类型标识
integer
- 对于浮点数有类型标识
number
- 对于整数有类型标识
- 取值约束
- 最小值约束
minimum
, 键值为允许的最小值 (可以相等) - 最大值约束
maximum
, 键值为允许的最大值 (可以相等) - 倍数约束
multipleOf
, 键值为浮点数, 要求倍约束值必须是键值的整数倍
- 最小值约束
字符串
- 类型标识
strgin
- 取值约束
- 最小长度约束
minLength
, 要求约束值得长度必须大于等于键值 - 最大长度约束
maxLength
, 要求约束值得长度必须小于等于键值 - 正则表达式约束
pattern
, 键值为正则表达式, 要求约束值必须满足
- 最小长度约束
数组
- 类型标识
array
- 取值约束
- 数组类型约束
items
, 键值为一个值模板对象, 表示被约束数组元素的模板 - 最小长度约束
minItems
, 要求约束值得长度必须大于等于键值 - 最大长度约束
maxItems
, 要求约束值得长度必须小于等于键值 - 唯一元素约束
uniqueItems
, 取值为true
时, 要求数组中不能有重复的元素 - 元组化约束
prefixItems
, 取值为一个由值模板组成的数组, 要求被约束数组对应位置元素类型与键值相同, 其余元素则受其他取值约束
- 数组类型约束
对象
- 类型标识
object
- 取值约束 (更多见文档)
- 键值约束
properties
, 取值为一个以值模板为值的对象, 要求被约束对象如果有对应的键, 则键值类型要满足要求 (不要求其中的键必须出现) - 其他键约束
additionalProperties
, 取值为false
时, 不允许出现键值约束properties
以外的键 - 必须键约束
required
, 取值为一个数组, 表面对象必须包含的键
- 键值约束
其他类型
- 对于空值有类型标识
null
- 对于布尔值有类型标识
boolean
- 枚举量
- 枚举量不需要类型标识, 而是直接使用键
enum
定义 - 键
enum
的值为一个数组, 包含了该枚举量所有允许的值
- 枚举量不需要类型标识, 而是直接使用键
- 常量
- 枚举量不需要类型标识, 而是直接使用键
const
定义 - 要求被约束值与键
const
的值相同 - 一般配合
oneOf
使用, 可用于标记使用的类型, 可见示例
- 枚举量不需要类型标识, 而是直接使用键
复合值模板
- 可以使用复合值模板代替一般的值模板标识复杂类型
- 复合值模板均为一个单键的对象, 且取值为一个以值模板为元素的数组
- 常用的复合值有
anyOf
表示被约束值满足其中任意值模板即可oneOf
表示被约束值只能满足其中一个值模板not
表示被约束值不能满足其中任何值模板
- 还允许将复合值模板视为值约束使用, 此时键值数组的元素为一个约束组成的对象, 因此可用于组合多个相同约束
模板示例
{
"$schema": "https://json-schema.org/draft-07/schema#",
"$id": "xxx.schema.json",
"title": "姿态对象",
"description": "用于描述一个姿态",
"type": "object",
"oneOf":[
{
"properties": {
"interface": {"const": "quat"},
"quat": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 4,
"maxItems": 4
}
},
"require": ["interface", "quat"]
},
{
"properties": {
"interface": {"const": "special"},
"type": {
"enum": ["identity", "random"]
}
},
"require": ["interface", "type"]
}
]
}
相关工具
- 不同语言的 JSON 模板验证模块 https://json-schema.org/implementations
- 在线 JSON 模板验证 https://json-schema.org/implementations#web-(online) (更推荐使用 vscode 的自动提示功能测试)
XML
基本介绍
- XML 全称为可扩展标记语言, 可用于传输与存储数据
- XML 文件一般使用后缀
.xml
- XML 通过自定义的标签为节点构成的树状结构来表达数据
- XML 的基本语法如下
- 将标签称为元素, 元素具有属性, 元素下可以是文本或子元素
- 所有数据都必须在一个根标签下
- 文件的第一行为 XML 声明, 一般为
<?xml version="1.0" encoding="UTF-8"?>
- XML 中以
<!--
开始, 以-->
结束, 用于包含注释内容
- 在 XML 文件的第二行还可以声明 XML 文件的模板, 更多参见 DTD 有关教程
元素
- 一般元素
- 即具有文本或子元素的元素, 使用如下的开始标签与结束标签包裹元素内容
- 开始标签
<xxx>
, 使用<>
包裹元素名 - 结束标签
</xxx>
, 改用</
为起始包含元素名, 要求元素的开始与结束标签必须有相同的元素名, 且区分大小写 - 应当保证元素间的正确嵌套, 即当元素
a
在元素b
内开始就必须在b
内结束
- 单标签
- 将仅具有属性而没有内容的元素使用单标签表示
- 单标签
<xxx/>
, 改用/>
为终止包含元素名, 注意空格
- 元素命名
- 元素名称最好仅包含字母, 数字, 下划线
- 元素名称不允许包含空格
- 元素名称不能以
xml
, 数字或下划线开头
- 元素属性
- 一个元素可以包含多个属性, 通过在开始标签后使用空格表示
- 单个属性使用
attr="value"
表示, 注意- 元素的值需要使用
"
或'
包裹 - 属性名与属性值之间使用
=
连接, 不允许有其他空格 - 属性名的命名要求与元素名类似, 但一个元素下不允许有同名属性
- 元素的值需要使用
- 由于一个属性只能有一个字符串, 没有树结构且不易拓展, 因此对于属性不应该存放任何数据, 而是使用子元素代替
- 推荐元素属性存放用于区分其他相同元素的元数据, 例如元素的 id
- 关于在属性值中使用特殊字符的表示见实体引用
- 元素文本
- 当元素的内容不包含
<
时将被视为存储文本 - 与 HTML 不同, 文本中的多个空格与换行不会被合并为一个
- 关于在文本内容中使用特殊字符的表示见实体引用
- 当元素的内容不包含
实体引用
- XML 中的表示文本或属性时不允许使用
<
与&
, 需要使用实体引用来表示这些字符 - 实体引用通常以
&
开始, 以;
结束, 使用中间的内容表示特定符号, 常用如下 (虽然部分字符允许直接使用, 但依然建议使用实体引用表示)<
表示<
>
表示>
'
表示'
"
表示"
&
表示&