跳至主要內容

文本数据存储语言

大约 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> 的键值对表示对象
    • value 可以是任意支持类型
    • key 一般为字符串, 不允许有重复的值
    • 注意冒号 : 与键相连, 与值之间存在一个空格
  • 使用单行 {key1: value1, key2: value2} 表示对象 (注意此处 : 依然有要求)

TOML

参见 https://toml.io/cn/open in new window

基本介绍

  • TOML 是一种专门用于表示配置文件的格式, 相比 YAML 更加稳定
  • TOML 文件使用后缀 .toml
  • TOML 的基本语法如下
    • 对大小写敏感, 且文档必须是 UTF-8 编码
    • 表示数据时, 将 与制表符视为空白, 其余均为需要解析的符号
    • 使用 # 用于注释内容的开始
  • TOML 支持数据类型
    • 对象 (TOML 中称为表)
    • 数组
    • 纯量

纯量表示

字符串 (TOML 中共有四种字符串)

  • 基本字符串, 使用 " 包裹, 仅能有单行
    • 基本字符串内可使用 \ 用于转义, 常用的如下
    • \t 制表符
    • \n 换行
    • \" 引号
    • \\ 反斜杠
    • \uXXXX unicode 字符
  • 多行字符串, 使用 """ 包裹
    • 多行字符串将包含换行符
    • 在单行文本末尾使用 \, 将忽略之后的换行与空格, 与最先出现的文本连接
    • 当文本末尾换行使用 """, 将导致文本末尾被加上一个换行, 此时可使用 \ 或让结尾的 """ 紧跟文本末尾
    • 多行字符串同样可以使用 \ 转义, 同基本字符串
  • 字面字符串, 使用 ' 包裹, 仅能有单行
    • 子面字符串不允许转义, 可用于表示正则表达式, 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

参见 https://www.json.org/json-zh.htmlopen in new window

基本介绍

  • JSON 本质为 Javascript 对象表示法, 可用于存储和交换文本信息, 读写速度较快
  • JSON 文件使用后缀 .json
  • JSON 的基本语法如下
    • 对大小写敏感
    • 对层级与缩进没有要求, 但一般会使用缩进增加可读性
    • 通常不允许注释
  • JSON 支持数据类型
    • JSON 值, 即单个不可分的值
    • 数组 (列表)
    • 对象 (键值对)

JSON 值

JSON 支持以下纯量

  • 布尔值
    • 使用关键字 ture 表示真值
    • 使用关键字 false 表示假值
  • 数字
    • 支持浮点数与整数, 但仅能使用十进制
    • 允许使用 eE 使用科学计数法表示数值
  • 字符串
    • 字符串只能使用双引号 " 包裹
    • 字符串内不允许有换行, 只能在单行内表示自负床
    • 使用 \ 作为转义符, 常用的有
      • \n 换行, \t 制表符
      • \u + XXXX unicode 字符, XXXX 为四位十六进制数
      • \", \\ 符号转义
    • 使用关键字 null 表示空

复合结构

  • 允许在表示复合结构时, 在结构符号之间插入任意的换行与空格
  • 一个 JSON 文件只能表示一个值, 因此通常以列表或对象作为基础
  • 列表表示
    • 使用 [] 包裹列表, , 分隔各个元素
    • 例如 [value1, value2, ...]
  • 对象表示
    • 使用 {} 包裹对象, : 分隔键与值, , 分隔各个键值对
    • 允许以任意 JSON 值作为键, 但是一个对象中不能有重复的键
    • 例如 {key1: value1, ...}

JSON 模板

参考 https://json-schema.org/learn/getting-started-step-by-stepopen in new window

由于 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
  • 取值约束 (更多见文档open in new window)
    • 键值约束 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"] 
        }
    ]
}

相关工具

XML

参考 https://www.runoob.com/xml/xml-tutorial.htmlopen in new window

基本介绍

  • XML 全称为可扩展标记语言, 可用于传输与存储数据
  • XML 文件一般使用后缀 .xml
  • XML 通过自定义的标签为节点构成的树状结构来表达数据
  • XML 的基本语法如下
    • 将标签称为元素, 元素具有属性, 元素下可以是文本或子元素
    • 所有数据都必须在一个根标签下
    • 文件的第一行为 XML 声明, 一般为
      <?xml version="1.0" encoding="UTF-8"?>
    • XML 中以 <!-- 开始, 以 --> 结束, 用于包含注释内容
  • 在 XML 文件的第二行还可以声明 XML 文件的模板, 更多参见 DTDopen in new window 有关教程

元素

  • 一般元素
    • 即具有文本或子元素的元素, 使用如下的开始标签与结束标签包裹元素内容
    • 开始标签 <xxx>, 使用 <> 包裹元素名
    • 结束标签 </xxx>, 改用 </ 为起始包含元素名, 要求元素的开始与结束标签必须有相同的元素名, 且区分大小写
    • 应当保证元素间的正确嵌套, 即当元素 a 在元素 b 内开始就必须在 b 内结束
  • 单标签
    • 将仅具有属性而没有内容的元素使用单标签表示
    • 单标签 <xxx/>, 改用 /> 为终止包含元素名, 注意空格
  • 元素命名
    • 元素名称最好仅包含字母, 数字, 下划线
    • 元素名称不允许包含空格
    • 元素名称不能以 xml, 数字或下划线开头
  • 元素属性
    • 一个元素可以包含多个属性, 通过在开始标签后使用空格表示
    • 单个属性使用 attr="value" 表示, 注意
      • 元素的值需要使用 "' 包裹
      • 属性名与属性值之间使用 = 连接, 不允许有其他空格
      • 属性名的命名要求与元素名类似, 但一个元素下不允许有同名属性
    • 由于一个属性只能有一个字符串, 没有树结构且不易拓展, 因此对于属性不应该存放任何数据, 而是使用子元素代替
    • 推荐元素属性存放用于区分其他相同元素的元数据, 例如元素的 id
    • 关于在属性值中使用特殊字符的表示见实体引用
  • 元素文本
    • 当元素的内容不包含 < 时将被视为存储文本
    • 与 HTML 不同, 文本中的多个空格与换行不会被合并为一个
    • 关于在文本内容中使用特殊字符的表示见实体引用

实体引用

  • XML 中的表示文本或属性时不允许使用 <&, 需要使用实体引用来表示这些字符
  • 实体引用通常以 & 开始, 以 ; 结束, 使用中间的内容表示特定符号, 常用如下 (虽然部分字符允许直接使用, 但依然建议使用实体引用表示)
    • &lt; 表示 <
    • &gt; 表示 >
    • &apos; 表示 '
    • &quot; 表示 "
    • &amp; 表示 &