Skip to main content

Yaml文件格式

基础概念

版本

  • 1.1
  • 1.2

什么是YAML

YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。

YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。

YAML 的配置文件后缀为 .yml

语法规则

  • 大小写敏感
  • 使用缩进表示层级关系
  • 空格作为缩进,且不允许使用tab
  • 缩进的数量没有指定,只要统一规则,2缩进、3缩进、4缩进等
  • ‘#’ 表示注释

数据类型

布尔值

male: true

# 对应json格式:
{ "male":true }
  • 强制转换类型
e: !!str 123
f: !!str true

# 对应json格式:
{ "e": '123', "f": 'true' }

数值

age: 18.5

# json
{ "age":18.5 }

字符串

字符串是最常见,也是最复杂的一种数据类型。

字符串默认不使用引号表示。

str: 我是字符串
str: '我是$字符串'


# 对应json
{ "str": '这是一行字符串' }

转义

# 双引号不会对特殊字符进行转义
s1: '我是:\n字符串'
s2: "我是:\n字符串"

# json
{ s1: '内容\\n字符串', s2: '内容\n字符串' }

单引号

单引号之中如果还有单引号,必须连续使用两个单引号转义
str: 'labor''s day'

# json
{ "str": "labor\'s day" }

换行

# 不保留换行
str: 这是一段
多行
字符串

# json
{ str: '这是一段 多行 字符串' }
# 保留换行
str: |
Foo
Bar
# json
{ "str": "Foo\nBar\n" }

保留、删除末尾的换行符

# "+" 和 "-"
s1: |
Foo
s2: |+
Foo
s3: |-
Foo

# json
{ s1: 'Foo\n', s2: 'Foo\n\n\n', s3: 'Foo' }

折叠

that: >
Foo
Bar

# json
{ that: 'Foo Bar\n' }

使用HTML

message: |

<p style="color: red">
段落
</p>

# json
{ message: '\n<p style="color: red">\n 段落\n</p>\n' }

合并引用(描点、引用)

  • 引用:* - 指定一个描点
  • 描点:& - 建立一个描点
  • 合并:<< - 合并到指定数据
# 数组中使用
- &showell Steve
- Clark
- Brian
- Oren
- *showell

# json
[ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ]
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),<<表示合并到当前数据,*用来引用锚点。

合并引用:


merge:
- &CENTER { x: 1, y: 2 }
- &LEFT { x: 0, y: 2 }
- &BIG { r: 10 }
- &SMALL { r: 1 }

# 等价于 sample1={r=10, y=2, x=1}
sample1:
<<: *CENTER
r: 10

# 等价于 sample2={other=haha, x=1, y=2, r=10}
sample2:
<< : [ *CENTER, *BIG ]
other: haha

# 等价于 sample3={r=100, y=2, x=1} r值被覆盖
sample3:
<< : [ *CENTER, *BIG ]
r: 100

Null 空值

name: ~

# json
{ name:null }

ISO8601 时间格式

iso8601: 2001-12-14t21:59:43.10-05:00 

# 对应 js
{ iso8601: new Date('2001-12-14t21:59:43.10-05:00') }
# 日期采用复合 iso8601 格式的年、月、日表示。
date: 1976-07-31

# 对应 js
{ date: new Date('1976-07-31') }

对象

# 定义一个对象
age: 18
name: Capsion

# 对应json格式:
{
"age":18
"name":"Capsion"
}
# 行内写法
Person: { name: Cpasion, age: 18 }

# 对应json格式:
{
"Person":{
"age":18
"name":"Capsion"
}
}

数组

# 创建一个名为 language 的数组
language:
- python
- nodejs
- javascript
- java

# 对应 json 格式
{
"language":['python', 'nodejs', 'javascript', 'java']
}
# 创建多维数组
-
- python
- nodejs
- javascript
- java

# 对应 json 格式
[['python', 'nodejs', 'javascript', 'java']]
# 行内写法
language: ['python', 'nodejs', 'javascript', 'java']

# 对应 json 格式
{ "language":['python', 'nodejs', 'javascript', 'java'] }

复合结构

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'
}
}

语言调用

javascript

使用 js-yaml 库

# example.yml
fn: function () { return 1 }
reg: /test/
var yaml = require('js-yaml');
var fs = require('fs');

try {
var doc = yaml.load(
fs.readFileSync('./example.yml', 'utf8')
);
console.log(doc);
} catch (e) {
console.log(e);
}
var yaml = require('js-yaml');
var fs = require('fs');

var obj = {
fn: function () { return 1 },
reg: /test/
};

try {
fs.writeFileSync(
'./example.yml',
yaml.dump(obj),
'utf8'
);
} catch (e) {
console.log(e);
}

python

yaml 模块

import yaml, json
from typing import *

def yaml_to_dict(file_name:str, encoding='utf8') -> dict:
import yaml
with open(file_name, 'r', encoding=encoding) as yaml_f:
yaml_str = yaml_f.read()
return yaml.load(yaml_str)

def print_dict(obj:dict, indent:int = 4) -> str:
import json
print("yaml_json: ", json.dumps(obj, indent=indent))

if ( __name__ == "__main__"):
target:str = './data.yaml'
print_dict(yaml_to_dict(target))

pyyaml 模块

官方地址

# 直接读取 yam l文件
yaml.load(stream, Loader=yaml.CLoader)

# 保存 yaml 文件
yaml.dump(data, Dumper=yaml.CDumper)

# 带检验的读取 yaml
yaml.safe_load(stream)

参阅文献