docker学习之YAML语法

776 阅读5分钟

什么是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语法介绍

YAML语法在线转换

基础语法

  • 基本语法
  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进不允许使用tab,只允许空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • '#'表示注释

基础类型(纯量)

  1. 字符串
string:
    - 'Hello world'  #可以使用双引号或者单引号包裹特殊字符
    - newline
      newline2    #字符串可以拆成多行,每一行会被转化成一个空格
=> js
{ string: [ 'Hello world', 'newline newline2' ] }
  1. 布尔值
boolean: 
    - TRUE  #true,True都可以
    - FALSE  #false,False都可以
=> js
{ boolean: [ true, false ] }
  1. 整数
int:
    - 12
    - 0b1110    #二进制表示
=> js
{ int: [ 12, 14 ] }
  1. 浮点数
float:
    - 3.1415926
    - 3.1415926e+5  #可以使用科学计数法
=> js
{ float: [ 3.1415926, 314159.26 ] }
  1. Null
null:
    nodeName: 'node'
    parent: ~  #使用~表示null
=> js
{ null: { nodeName: 'node', parent: null } }
  1. 时间
date:
    - 2019-11-19    #日期必须使用ISO 8601格式,即yyyy-MM-dd
=> js
{ date: [ Tue Nov 19 2019 08:00:00 GMT+0800 (中国标准时间) ] }
  1. 日期
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' ] 
            } 
        ] 
    } 
]

引用

  • & 锚点和 * 别名,可以用来引用
  1. 对象中使用
people: &people
  name:  detanx
  age:     24
man:
  sex: 男
  <<: *people
=> js
{ people: { name: 'detanx', age: 24 },
  man: { sex: '男', name: 'detanx', age: 24 } }

注:& 用来建立锚点(people),<< 表示合并到当前数据,* 用来引用锚点。

  1. 数组中使用
- detanx 
- &name 16 
- 男 
- *name 
=> js
[ 'detanx', 16, '男', 16 ]