YAML 官方文档:https://yaml.org/
1 简介
YAML("YAML Ain't a Markup Language",YAML 不是标记语言)是一种数据序列化语言,旨在对人类友好,并且可以与现代编程语言很好地配合日常日常工作。
开放,可互操作且易于理解的工具极大地提高了计算能力。YAML 从一开始就被设计为对使用数据的人员有用且友好。 它使用 Unicode 可打印字符,其中一些字符提供结构信息,其余字符包含数据本身。YAML 通过最大程度地减少结构特征的数量并允许数据以自然而有意义的方式展示自身,从而实现了独特的清洁度。例如,缩进可以用于结构,冒号用于分隔key: value 对和 - 用于创建“项目符号”列表。
数据结构有无数种形式,但是它们都可以用三个基本结构表示:映射(哈希/字典),序列(数组/列表)和标量(字符串/数字)。YAML 利用了这些基本结构,并添加了简单的 typing 系统和别名机制来形成用于序列化任何 native 数据结构的完整语言。尽管大多数编程语言都可以使用 YAML 进行数据序列化,但是 YAML 擅长使用那些基本上围绕三个基本原语构建的语言。这些包括新的敏捷语言,例如 Perl,Python,PHP,Ruby 和 Javascript。
YAML 还是专门为在常见的用例(如配置文件,日志文件,进程间消息传递,跨语言数据共享,对象持久性以及复杂数据结构的调试)提供支持。当数据易于查看和理解时,编程将变得更加简单。
1.1 目标
YAML 的设计目标是降低复杂性:
- YAML 易于人类阅读。
- YAML 数据可在编程语言之间移植。
- YAML 与敏捷语言的本机数据结构匹配。
- YAML 具有一致的模型来支持通用工具。
- YAML 支持 one-pass 处理。
- YAML 具有表现力和可扩展性。
- YAML 易于实现和使用。
1.2 语言特性
YAML 基于缩进的作用域与 Python 相似(没有制表符引起的歧义)。缩进的块便于检查数据结构。YAML 的文字风格利用了这一点,可以使格式化的文本在缩进的结构中干净地混合在一起,而不会产生麻烦的转义。YAML 还允许使用类似于 JSON 和 Perl 的基于指标的传统范围。这样的流内容可以自由地嵌套在缩进的块中。
YAML 的双引号样式使用了熟悉的 C 样式转义序列。这将启用不可打印或 8 位(ISO 8859-1)字符(例如"\x3B")的 ASCII 编码。 转义序列(例如 “\u003B” 和 “\U0000003B”)支持不可打印的 16 位 Unicode 和 32 位(ISO / IEC 10646)字符。
受 HTML 的行尾规范化影响,YAML 的行折叠采用了一种直观的方法来处理换行符。单个换行符被折叠到一个空格中,而空行则被解释为换行符。此技术允许对段落进行单词包装,而不会影响标量内容的规范形式。
YAML 的核心类型系统基于 Perl,Python 和 Ruby 等敏捷语言的要求。YAML 直接支持集合(映射,序列)和标量。对这些通用类型的支持使程序员可以将其语言的本机数据结构用于 YAML 操作,而不需要特殊的文档对象模型(DOM)。
与 XML 的 SOAP 一样,YAML 支持通过别名机制对 native 数据结构图进行序列化。与 SOAP 一样,YAML 也提供了应用程序定义的类型。这使 YAML 可以代表现代分布式计算所需的丰富数据结构。YAML 使用受 Java 的基于 DNS 的软件包命名约定和 XML 的基于 URI 的命名空间启发的命名空间机制来提供全局唯一类型名称。另外,YAML允许特定于单个应用程序的私有类型。
YAML旨在支持增量接口,该接口包括输入(getNextEvent)和输出(sendNextEvent)one-pass 接口。 这些特性共同使 YAML 支持大型文档(例如交易日志)或连续流(例如来自生产机器的提要)的处理。
1.3 PyYaml
官方推荐的 YAML 文件扩展名是 .yaml 或者 .yml。 Python 中有两个用于 YAML 的模块:PyYAML 和 ruamel.yaml。在本教程中,我们使用前者。
YAML 支持三种基本数据类型:标量(例如字符串,整数和浮点数),列表和关联数组。
安装:
pip install pyyaml
2 基本语法
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用 tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
-
#表示注释
2.1 数据类型
YAML 支持以下几种数据类型:
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
- 标量(scalars):单个的、不可再分的值
2.2 YAML 对象
对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。也可以使用 key:{key1: value1, key2: value2, ...}。还可以使用缩进表示层级关系:
key:
child-key: value
child-key2: value2
较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value:
?
- complexkey1
- complexkey2
:
- complexvalue1
- complexvalue2
意思即对象的属性是一个数组 [complexkey1,complexkey2],对应的值也是一个数组 [complexvalue1,complexvalue2]。
2.3 YAML 数组
以 - 开头的行表示构成一个数组:
- A
- B
- C
YAML 支持多维数组,可以使用行内表示:
key: [value1, value2, ...]
数据结构的子成员是一个数组,则可以在该项下面缩进一个空格:
-
- A
- B
- C
一个相对复杂的例子:
companies:
-
id: 1
name: company1
price: 200W
-
id: 2
name: company2
price: 500W
意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。
数组也可以使用流式(flow)的方式表示:
companies: [{id: 1,name: company1,price: 200W},{id: 2,name: company2,price: 500W}]
2.4 复合结构
数组和对象可以构成复合结构,例:
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org
转换为 JSON:
{
languages: [ 'Ruby', 'Perl', 'Python'],
websites: {
YAML: 'yaml.org',
Ruby: 'ruby-lang.org',
Python: 'python.org',
Perl: 'use.perl.org'
}
}
也可以是:
-
name: Mark McGwire
hr: 65
avg: 0.278
-
name: Sammy Sosa
hr: 63
avg: 0.288
或者
- [name , hr, avg ]
- [Mark McGwire, 65, 0.278]
- [Sammy Sosa , 63, 0.288]
或者
Mark McGwire: {hr: 65, avg: 0.278}
Sammy Sosa: {
hr: 63,
avg: 0.288
}
2.5 标量
标量是最基本的,不可再分的值,包括:字符串、布尔值、整数、浮点数、Null、时间、日期。
使用一个例子来快速了解标量的基本使用:
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科学计数法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二进制表示
null:
nodeName: 'node'
parent: ~ #使用~表示null
string:
- 哈哈
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- newline
newline2 #字符串可以拆成多行,每一行会被转化成一个空格
date:
- 2018-02-17 #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2018-02-17T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区

YAML’s flow scalars include the plain style (most examples thus far) and two quoted styles. The double-quoted style provides escape sequences. The single-quoted style is useful when escaping is not needed. All flow scalars can span multiple lines; line breaks are always folded.

3 Structures
YAML 使用 --- 分隔文本上下文,... 标识上下文的结束(Three dots ( “...”) indicate the end of a document without starting a new one, for use in communication channels.):

3.1 引用
& 锚点和 * 别名,可以用来引用:
defaults: &defaults
adapter: postgres
host: localhost
development:
database: myapp_development
<<: *defaults
test:
database: myapp_test
<<: *defaults
相当于:
defaults:
adapter: postgres
host: localhost
development:
database: myapp_development
adapter: postgres
host: localhost
test:
database: myapp_test
adapter: postgres
host: localhost
& 用来建立锚点(defaults),<< 表示合并到当前数据,* 用来引用锚点。
下面是另一个例子:
- &showell Steve
- Clark
- Brian
- Oren
- *showell
转换为 JavaScript 代码如下:
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]

4 Tags
In YAML, untagged nodes are given a type depending on the application. The examples in this specification generally use the seq, map and str types from the fail safe schema. A few examples also use the int, float, and null types from the JSON schema. The repository includes additional types such as binary, omap, set and others.

Explicit typing is denoted with a tag using the exclamation point (“!”) symbol. Global tags are URIs and may be specified in a tag shorthand notation using a handle. Application-specific local tags may also be used.

5 例子
