YAML 全名 YAML Ain’t Markup Language,主要设计目标是对人类可读性高。 YAML 1.2 是 JSON 的超集,也就是说合法的 JSON 扔给 YAML 1.2 解析器是可以被完美解析的。YAML 集 JSON 和 XML 等各种标记语言之长,进行了扩展强化,功能全面也很易读,很多的系统采用它作为配置文件的格式。
示例
fruits:
- apple1:
color: red
- apple2:
color: green
- pear
上面的 YAML 等同于 JSON:
{
"fruits": [
{
"apple1": {
"color": "red"
}
},
{
"apple2": {
"color": "green"
}
},
"pear"
]
}
是不是看上去简洁了很多,也更容易阅读很多?
YAML 的基本结构
缩进符
YAML 的缩进只能用空格而不能用 tab,一个主要的原因是不同的系统对 tab 的处理不完全一致(比如有的系统把 tab 处理成 4 个空格,有的系统把 tab 处理成 8 个空格)。好在现代的文本编辑器基本都支持把 tab 转换成指定数量的空格。
YAML 里的元素都是用缩进来匹配层级关系的,简单说就是缩进相同的都是同级元素,缩进比上一个元素长就是上一个元素的子元素。
具体的例子如下:
- apple1:
color: red
- apple2:
color: green
对应的 JSON:
[
{
"color": "red",
"apple1": null
},
{
"apple2": {
"color": "green"
}
}
]
请自行体会,我就不展开了。为了方便理解说一下前面的 YAML 等同于:
-
apple1:
color: red
-
apple2:
color: green
分隔符
只要不是行首的缩进符,其它地方的词法分隔符是可以用各种 white space 字符的。但是要注意这是 YAML 1.2 的规则,在 YAML 1.1 里还是严禁用 tab 作分隔符的。我认为 YAML 1.2 做出这样的更改主要也是为了兼容 JSON。目前解析 YAML 的大部分库还是仅支持 YAML 1.1,所以为了兼容性, 分隔符最好还是不要用 tab 。
注释
YAML 使用 “#” 来进行注释,”#” 及在其之后的当行内容将被忽略。注意 “#” 如果跟在别的元素后面,和元素之间需要用 white space 字符隔开。
多行文本的种种
说起来会絮絮叨叨的,懒得说了……请自行看 官网文档 。
YAML 的纯量(Scalar)
这就是大部分语言里的基础类型,YAML 里常用的纯量有以下类型:
null
~
/ null
/ Null
/ NULL
还有空字符都被解析成 null 类型,最标准的写法是 ~
。
bool
最新标准里 y
/ Y
/ yes
/ Yes
/ YES
/ n
/ N
/ no
/ No
/ NO
/ true
/ True
/ TRUE
/ false
/ False
/ FALSE
/ on
/ On
/ ON
/ off
/ Off
/ OFF
全部都会被解析成正确的 bool 类型,为了兼容性比较好建议用 true
和 false
。
举个例子,我使用的在线解析器解析如下 YAML:
- on
- On
- no
- No
- n
- N
解析出的 JSON:
[
true,
true,
false,
false,
"n",
"N"
]
int
很常规就不多介绍了,YAML 支持 8 进制和 16 进制格式的数据,甚至 2 进制和 60 进制。
float
支持常规的浮点数,支持科学计数法,还支持无穷大和 NaN。详情可以参考 tag:yaml.org,2002:float 。
str
大部分情况下,YAML 里的字串是不需要带引号的,某些容易引起解析歧义的字串可以用引号括起来。
示例 YAML:
- a b c
- "a\n\x20b"
- 'a\n\x20b'
- "'\""
- '''"'
- 123 # 有歧义,会被解析成 int
- '123'
- yes # 有歧义,会被解析成 bool
- 'yes'
- a: b # 有歧义,会被解析成 map
- 'a: b'
对应 JSON:
[
"a b c",
"a\n b",
"a\\n\\x20b",
"'\"",
"'\"",
123,
"123",
true,
"yes",
{ "a": "b" },
"a: b"
]
顺带说明下双引号会对转义符进行操作,而单引号不会。双引号内包含双引号可以用 \"
来表示,单引号内包含单引号可以用 ''
来表示。
其它纯量
其它纯量是很不常用的类型,可以自行查阅(官方文档)[ http://yaml.org/type/]。
类型强转
另外要提一点,YAML 支持类型强转:
- 123
- !!str 123
对应 JSON:
[
123,
"123"
]
字典(Mapping)和数组(Sequence)
基本用法
字典:
a: b
c: d
对应 JSON:
{
"a": "b",
"c": "d"
}
数组:
- a
- b
对应 JSON:
[
"a",
"b"
]
嵌套使用
字典的 value 为数组:
a:
- b
- c
d:
- e
- f
对应 JSON:
{
"a": [
"b",
"c"
],
"d": [
"e",
"f"
]
}
数据的元素为字典:
-
a: b
- d: e
对应 JSON:
[
{
"a": "b"
},
{
"d": "e"
}
]
类 JSON 的行内写法
数组有一种类似 JSON 的写法,可以完成行内数组的功能,当然和 JSON 一样写成多行的也可以:
[a, b]
对应 JSON:
[
"a",
"b"
]
字典也可以用类似 JSON 的方法写成行内的:
{a: b}
对应 JSON:
{
"a": "b"
}
引用
引用是 YAML 的一个很方便的高级语法,示例如下:
name: &name Jason
relation:
- &info
name: Sara
age: 23
- name: *name
age: 25
wife: *info
解析出的对应 JSON:
{
"relation": [
{
"age": 23,
"name": "Sara"
},
{
"age": 25,
"name": "Jason",
"wife": {
"age": 23,
"name": "Sara"
}
}
],
"name": "Jason"
}
可以看到基本的规则就是用 &
声明一个引用,然后在其他地方用 *
进行展开,有点像 c 语言的指针操作。
引用的部分就是在 &
之后的整个子元素,上面例子里 &name
引用的是 Jason
,而 &info
引用的是:
name: Sara
age: 23
在后面使用对应的名称展开后就得到了最终的 JSON 内容。