设定档格式 YAML

YAML

YAML的诞生不算太晚, 1.0在2004就出了, 虽然晚了JSON 5年(1999年), 但算是蛮迅速就被开发者们给接受了
相较於INI, YAML所支持的层级, 资料类型可就丰富了,
支持的结构也从来到3种(Mapping、Collection、Scalars)
它主档的口号如下

YAML Ain't Markup Language
YAML is a human friendly data serialization
language for all programming languages.

第一句YAML Ain't Markup Language就是YAML全名了
就是希望全程序语言都能用, 对人类好阅读跟设计.

YAML有几个特徵

  • 使用Indent表示层级关系(越靠左的, 越上层)
    • 其实Tab不支持, 但IDE会帮忙转成对应的Space
    • indent的space数量其实不重要, 但第一个定义出来的层级元素, 之後相同层级的元素,都需要左对齐
parent:
  son1: 1 #2个space
  son2:   #因为想要同层级, 所以同上是2个space
   grandson: 3 #4个space
   sonofgrandson: #因为想要同层级, 所以同上是4个space
       grandgrandson: 4 #随意个space, 反正比4多

转成对应的JSON

{
  "parent": {
    "son1": 1,
    "son2": {
      "grandson": 3,
      "sonofgrandson": {
        "grandgrandson": 4
      }
    }
  }
}
  • Case sensitive, 大小写不同视为不同变数
    A: 1
    a: 1
    
  • # 注解, 後面整行都是注解, 随时都能加入注解
  • JSON的super set
  • String未必要用'"包起来, 除非有必要
  • 可以型态转型!!, 但我其实自己不懂这有什麽实际用途
  • 可以有多分Document
    • ---为开始, ...为document的结束
    • 可以多个Document, 就相同於JSON的file, 但yaml可以在一只档案内, 透过---...来撰写
    • 每个Document之间彼此独立
---
# 1nd document
ithome: 12th
...

--- 
# 2nd document
ithome: 13th
...

YAML的基本资料节点

  • Scarlar
    • String
    • Boolean
    • Integer
    • Float
    • Null
    • Timestamp (Canonical、ISO8601、Date)
ithome:
  strings:
  - Hi eveny iron man
  year: 2021
  finished: False
  beginDate: 2021-09-01
  nullType:

转成对应的JSON

{
  "ithome": {
    "strings": [
      "Hi eveny iron man"
    ],
    "year": 2021,
    "finished": false,
    "beginDate": "2021-09-01T00:00:00.000Z",
    "nullType": null
  }
}
  • Collections
    • -[]表示
ithome:
    years:
    - 2021
    - 2020
    - 2019
    terms: [13th, 12th, 11th]

转成对应的JSON

{
  "ithome": {
    "years": [
      2021,
      2020
    ],
    "terms": [
      "13th",
      "12th"
    ]
  }
}
  • Mapping/Dictionary/Object
    • key: value
    • 支持Nested Mapping, 如上面所描述, 用indent表示层级关系
      上面展示的例子都是Mapping了

String类型的几种多行写法与indicators:
|>
先看sample

preserved: |
  65 Home Runs
  0.278 Batting Average
    Mark McGwire's
      year was crippled

folded: >
  Your long
  string here.
  
  Second string here.
  
  
  Last string here.

转成对应的JSON

{ preserved: '65 Home Runs\n0.278 Batting Average\n  Mark McGwire\'s\n    year was crippled\n',
 folded: 'Sammy Sosa completed another fine season with great stats.\n\n  63 Home Runs\n  0.288 Batting Average\n\nWhat a year!\n' }

|只要碰到yaml换行就是换行, 然後之後其他行是对齐第一行的indent, 但若是自己多打的额外indent则会被保留, 像是Mark McGwire's跟第一行相比多缩进的两个space, 就会被保留.

>换行方式比较特别, 要遇到空白行, 会把前一句的\n给修剪掉, 并且在最後输出一个\n
可以看到第一个\n出现在Second前面, 因为第一个here後面有一个\n(这个被移除), 然後接一个空白行\n.
第二句最後转出json是\n\n, 第二个here後面的\n一样被移除, 接两个空白行\n\n, 就输出这两个了

|>搭配+或是-
+就是最後多加个\n
-反之就是最後把最後的\n删除

preserved: |
  12th
  13th

preservedPlu: |+
  12th
  13th
  
preservedMinus: |-
  12th
  13th
{ preserved: '12th\n13th\n',
  preservedPlu: '12th\n13th\n\n',
  preservedMinus: '12th\n13th' }

Anchor锚点& 与 Alias引用*

当Yaml文件中, 有多处的重复内容时, 可以透过Anchor与Alias来快速引用相同的内容.
在字串类型上的应用, 当对同一个Anchor名称定义内容时, 能做覆写

ithome: &anchor |
  11th
  12th
  
reuseFirst: *anchor

override: &anchor | 
  12th
  13th
  
reuseSecond: *anchor
{ ithome: '11th\n12th\n',
  reuseFirst: '11th\n12th\n',
  override: '12th\n13th\n',
  reuseSecond: '12th\n13th\n' }

阵列元素的重复引用

---
hr:
- Mark McGwire
# Following node labeled SS
- &SS Sammy Sosa
rbi:
- *SS # Subsequent occurrence
- Ken Griffey
{ hr: [ 'Mark McGwire', 'Sammy Sosa' ],
  rbi: [ 'Sammy Sosa', 'Ken Griffey' ] }

於mapping类型的应用
这里会看到<<这个符号, 这是用来merge mapping的key
当如果需要修改原本的key, 或者新增key,
就需要<<来merge, 如果只是纯引用, 则不必

defaults: &defaults
  year:  2021
  terms: 13th
  name: iT邦帮忙

development:
  *defaults

newFeature:
  <<: *defaults
  name: iT邦个忙
{ defaults: { year: 2021, terms: '13th', name: 'iT邦帮忙' },
  development: { year: 2021, terms: '13th', name: 'iT邦帮忙' },
  newFeature: { year: 2021, terms: '13th', name: 'iT邦个忙' } }

现在最常见到YAML的应用场景
大概就是Docker-Compose文件与K8S文件
范例来源DoockerCompose

version: "3.9"
x-volumes:
  &default-volume #  Anchor宣告
  driver: foobar-storage

services:
  web:
    image: myapp/web:latest
    volumes: ["vol1", "vol2", "vol3"]
volumes:
  vol1: *default-volume #  引用Anchor
  vol2:
    << : *default-volume # 引用Anchor并Merge keys
    name: volume02
  vol3:
    << : *default-volume # 引用Anchor并Merge keys
    driver: default
    name: volume-local
{ version: '3.9',
  'x-volumes': { driver: 'foobar-storage' },
  services: 
   { web: 
      { image: 'myapp/web:latest',
        volumes: [ 'vol1', 'vol2', 'vol3' ] } },
  volumes: 
   { vol1: { driver: 'foobar-storage' },
     vol2: { driver: 'foobar-storage', name: 'volume02' },
     vol3: { driver: 'default', name: 'volume-local' } } }

本日小结

YAML具有多种Type的表示, 也能透过Anchor达到内容覆用.
但其实蛮复杂的XD, 目前在WebService的传输协议上, 可见度很低, 几乎还是JSON居多.
但作为像Docker-compose或k8s这种需要多组服务的设定时,
确实比起上一篇的ini, 更能表现出复杂设定时的便利性

ps. YAML 1.2.2 於2021/10/1号刚好释出了

参考资料

YAML org


<<:  虹语岚访仲夏夜-19(专业的小四篇)

>>:  D-12 设定挡 ? configuration ? IOptionsMonitor

[Day 1]-前言

铁人赛来到了第13届,作为资讯人,在这次参赛之前,我也透过铁人赛学习到许多,但直到现在,我才鼓起勇气...

[DAY 12]让BOT 24小时在线(3/3)

今天分享程序码从github更新到replit的步骤还有要注意的点 步骤 replit有自带储存环境...

【这些年我似是非懂的 Javascript】Day 30 - 完赛心得

今天是最後一天铁人赛, 好像没有完赛心得就不完美了一样, 原本想说不应该在三十天时写心得, 毕竟这...

虚拟机器监视器(Hypervisor)

-虚拟机和容器部署(来源:NIST SP 800-190) 虚拟机器监视器(Hypervisor)...

Day 17 ( 中级 ) 立体空间 ( 三度空间 )

立体空间 ( 三度空间 ) 教学原文参考:立体空间 ( 三度空间 ) 这篇文章会介绍,如何在 Scr...