什么是YAML
YAML是一个可读性高,用来表达数据序列化的格式。百度百科
适用场景
脚本语言
- 由于实现简单,解析成本很低,YAML特别适合在脚本语言中使用。列一下现有的语言实现:Ruby,Java,Perl,Python,PHP,OCaml,JavaScript,Go 。除了Java 和 Go,其他都是脚本语言。
序列化
- YAML比较适合做序列化。因为它是宿主语言数据类型直转的。
配置文件
- YAML做配置文件也不错。写YAML要比写XML快得多(无需关注标签或引号),并且比ini文档功能更强。
- 比如Ruby on Rails的配置就选用的YAML。对ROR而言,这很自然,也很省事。
- 由于兼容性问题,不同语言间的数据流转建议不要用YAML。
YAML的特点
对比JSON
- JSON的语法是YAML1.2版的子集,同时非常接近YAML1.0与1.1版的子集,因此大部分的JSON文件都可以被YAML的剖析器剖析。这是因为JSON的语法结构和YAML的内置格式相同。虽然大范围的分层也可以使用类似JSON的内置格式,不过YAML标准并不建议这样使用,除非这样编写能让文件可读性增加。YAML的许多扩展在JSON是找不到的,如:进阶资料形态、关系锚点、字串不需要双引号、映射资料形态会储存键值的顺序。
XML和SDL
- XML和SDL标签概念,在YAML中是找不到的。对于数据结构序列(尽管这是有争议的),标签属性的特色就是可以将资料及复杂资料附加资讯分离,并将各种原生数据结构(如:杂凑表、阵列)用同一种语言表示。YAML则以资料的可扩展性作为替代。(包括为了模拟物件的类别型态)在YAML本身的规范中,并没有类似XML的语言定义文件纲要(language-defined document schema descriptors)──例如验证自己本身的结构是否正确的文件。不过,YAML纲要描述语言(YAML schema descriptor language)是存在的。另外还有YAXML──用XML描述YAML的结构──可以让XML Schema与XSLT转换程式应用在YAML之上。况且,在一般使用的情况下,YAML丰富的定义型态之语法已经提供了足够的方式来辨认YAML文件是否正确。
缩排划界
- YAML类似Python语法,使用严格的缩进控制所属的内容的层级,但并不像python那么严格。
非阶层式的资料模型
跟SDL、JSON等,每个子结点只能有单一一个父节点的阶层式模型不同,YAML提供了一个简单的关系体制,可以从树状结构的其他地方,重复相同的资料,而不必显示那些冗余的结构
实际的考量
YAML是“行导向的”,因此,就算想由现有程序的混乱输出,转换成YAML格式,并保留大部分的原始文件之外观,也非常简单。因为他不需要平衡封闭的标签、括号及引号,可以从很简单的利用程式,从报表产生YAML。同样,空格分隔可让使用行导向的命令如:grep、Awk、perl、ruby,和Python,来应急性的过滤YAML文件时更加方便。
安全性
- YAML是纯粹用来表达资料的语言,所以内部不会存代码注入的可执行命令。
YAML语法介绍
基础语法
- 基本语法
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不允许使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
基础类型(纯量)
- 字符串
string:
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- newline
newline2 #字符串可以拆成多行,每一行会被转化成一个空格
=> js
{ string: [ 'Hello world', 'newline newline2' ] }
- 布尔值
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
=> js
{ boolean: [ true, false ] }
- 整数
int:
- 12
- 0b1110 #二进制表示
=> js
{ int: [ 12, 14 ] }
- 浮点数
float:
- 3.1415926
- 3.1415926e+5 #可以使用科学计数法
=> js
{ float: [ 3.1415926, 314159.26 ] }
- Null
null:
nodeName: 'node'
parent: ~ #使用~表示null
=> js
{ null: { nodeName: 'node', parent: null } }
- 时间
date:
- 2019-11-19 #日期必须使用ISO 8601格式,即yyyy-MM-dd
=> js
{ date: [ Tue Nov 19 2019 08:00:00 GMT+0800 (中国标准时间) ] }
- 日期
datetime:
- 2019-11-19T15:40:00+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
=> js
{ datetime: [ Tue Nov 19 2019 15:40:00 GMT+0800 (中国标准时间) ] }
对象
- 对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
- 对象键值对使用冒号结构表示 key: value,冒号后面要加一个空格。也可以使用 key:{key1: value1, key2: value2, ...}。
detanx:
hello detanx
# or
detanx: hello detanx #可以使用双引号或者单引号包裹特殊字符
=> js
{ detanx: 'hello detanx' }
- 较为复杂的对象格式,可以使用问号加一个空格代表一个复杂的 key,配合一个冒号加一个空格代表一个 value
?
- hello
- detanx
:
- hello
- detanx
=> js
{ 'hello,detanx': [ 'hello', 'detanx' ] }
数组
- 细心的读着应该早就发现在上面很多的例子🌰中都有数组的出现,在
YAML中以 - 开头的行表示构成一个数组,也可以使用行内表示:['value1','value2',...]
- hello
- detanx
# or
['hello','detanx']
=> js
['hello','detanx']
YAML也可以表示多维数组,只需要控制相应的缩进就行
-
- man
- woman
-
- banana
=> js
[ [ 'man', 'woman', [ 'banana' ] ] ]
数组对象结合
-
name:
- detanx
-
people:
- man
- woman
fruit:
- apple
- banana
=> js
[ { name:
[
'detanx',
{
people: [ 'man', 'woman' ],
fruit: [ 'apple', 'banana' ]
}
]
}
]
引用
&锚点和*别名,可以用来引用
- 对象中使用
people: &people
name: detanx
age: 24
man:
sex: 男
<<: *people
=> js
{ people: { name: 'detanx', age: 24 },
man: { sex: '男', name: 'detanx', age: 24 } }
注:& 用来建立锚点(people),<< 表示合并到当前数据,* 用来引用锚点。
- 数组中使用
- detanx
- &name 16
- 男
- *name
=> js
[ 'detanx', 16, '男', 16 ]