YAML – 信息模型
YAML - 数据模型与表示图
Section titled “YAML - 数据模型与表示图”为了有效地使用和理解 YAML,了解其底层信息模型(information model)会很有帮助。当一个 YAML 文档被处理时,它会被转换成一个抽象数据结构,通常称为“表示图(representation graph)”或“节点图(node graph)”。应用程序与这个图交互,而不是直接与原始的 YAML 文本交互。
YAML 表示图
Section titled “YAML 表示图”YAML 中原生应用程序数据的表示被建模为一个带有标签节点的、有根、连接的、有向图(rooted, connected, directed graph of tagged nodes)。我们来分解一下:
- 图(Graph):节点的集合(数据项)和边(节点之间的关系)。
- 有向(Directed):关系有方向(例如,一个映射节点指向其键节点和值节点)。
- 有根(Rooted):图有一个单一的起始点(YAML 文档的根节点)。
- 连接(Connected):所有节点都可以从根节点到达。
- 带有标签的节点(Tagged Nodes):图中的每个节点都有一个标签(tag),指定其数据类型(例如,字符串、整数、序列、映射)。
整个转换过程可以视为:
应用程序数据 ⇔ YAML 节点图(标量、序列、带有标签的映射)⇔ YAML 文本表示
核心节点类型
Section titled “核心节点类型”YAML 节点图主要由三种节点组成:
1. 标量节点
Section titled “1. 标量节点”表示单一的原子数据值(atomic data values)。其内容是 Unicode 字符序列。示例包括字符串、数字、布尔值、日期和 null 值。每个标量节点都有一个标签(tag)(例如 !!str、!!int、!!bool、!!null、!!timestamp),用于定义如何解释其字符内容。
2. 序列节点
Section titled “2. 序列节点”表示零个或多个其他节点的有序系列(ordered series)。这对应于编程语言中的列表(lists)或数组(arrays)。序列节点包含一个有序的子节点列表。其典型标签是 !!seq。
3. 映射节点
Section titled “3. 映射节点”表示键值对(key-value pairs)的无序关联。这对应于字典(dictionaries)、对象(objects)或哈希映射(hash maps)。映射节点包含一组对,每对由一个键节点(key node)和一个值节点(value node)组成。映射中的键必须是唯一的。映射节点的典型标签是 !!map。虽然键通常是标量节点,但 YAML 允许键是复杂节点(序列或映射本身)。
序列和映射统称为“集合节点(collection nodes)”。
标签:指定数据类型
Section titled “标签:指定数据类型”YAML 图中的每个节点都有一个标签(tag)。标签至关重要,因为它们决定了节点内容的解释方式。虽然 YAML 通常根据语法推断标签(例如,123 被推断为 !!int,true 被推断为 !!bool),但标签也可以显式指定:
- 全局标签(缩写):
!!tagname(例如,!!str,!!map)。这些是标准 YAML 标签集的一部分。 - 主标签(应用特定或本地):
!tagname(例如,!person,!config-setting)。这些可以由应用程序定义。 - 次级标签(
!<prefix>!tagname):用于更复杂的基于 URI 的标签,在日常使用中不太常见。
节点图结构示例:
# YAML 文档user_profile: # 根节点,隐式为映射 (!!map) name: Alice # 标量节点 (!!str),'user_profile' 的子节点 age: 30 # 标量节点 (!!int),'user_profile' 的子节点 hobbies: # 序列节点 (!!seq),'user_profile' 的子节点 - reading # 标量节点 (!!str),'hobbies' 的子节点 - coding # 标量节点 (!!str),'hobbies' 的子节点这段 YAML 在内部会被表示为一个图,其中 user_profile 是一个映射节点。这个映射节点有三个子条目:一个用于 name(键),指向 Alice(值,一个标量字符串节点);一个用于 age(键),指向 30(值,一个标量整数节点);还有一个用于 hobbies(键),指向一个序列节点。hobbies 序列节点则有两个子标量字符串节点:reading 和 coding。
锚点和别名:创建图(不仅仅是树)
Section titled “锚点和别名:创建图(不仅仅是树)”YAML 的锚点(anchor)(&)和别名(alias)(*)机制允许在文档中多次引用同一个节点。这意味着表示图确实可以是一个具有循环或共享子结构的普通图,而不仅仅是一个简单的树。当遇到别名时,它指向由锚点标记的同一个节点实例。
default_address: &addr street: 123 Main St city: Anytown
billing_address: *addrshipping_address: *addr在这种情况下,billing_address 和 shipping_address 都指向由 &addr 定义的完全相同的映射节点实例。
为什么这个模型很重要?
Section titled “为什么这个模型很重要?”- 可移植性(Portability):它提供了一种跨不同编程语言和环境思考 YAML 数据的通用方式。
- 理解 YAML 库(Libraries):它阐明了 YAML 解析器(parsers)和序列化器(serializers)的内部工作原理。
- 高级数据结构化:它有助于使用锚点、别名和自定义标签等特性设计复杂的数据关系。
- 调试:理解预期的节点结构有助于诊断 YAML 解析或生成中的问题。
对于那些对最正式细节感兴趣的人,官方 YAML 规范(可在 yaml.org 获取)提供了对其信息模型和处理规则的深入描述。