yaml 入门
稍微重构了一下博客,因此学习一下这门语言
YAML 入门
YAML 概述
YAML 是一种用于数据序列化的轻量级语言,具有易读、易写的特点。它的名称 "YAML" 是 "YAML Ain't a Markup Language" 的递归缩写,这意味着 YAML 不是一种标记语言。然而,在最初的开发阶段,YAML 的全称其实是 "Yet Another Markup Language"(仍是一种标记语言),但随着其发展和使用,YAML 被重新定位为一种数据序列化格式,而非传统的标记语言。
YAML 的用途
YAML 被广泛用于配置文件和数据交换,特别是在需要人类可读性的场景下。它的语法简单直观,非常适合表示清单(列表)、散列表(键值对),以及标量(单一值)等复杂的数据结构。这使得 YAML 成为开发人员用来编写配置文件、数据输入输出、调试和文件大纲的理想选择。
YAML 的文件后缀
YAML 文件通常使用 .yaml
或 .yml
作为文件扩展名。例如,config.yml
或
runoob.yaml
。两者在语法上没有任何区别,选择哪种取决于个人或项目的约定。
YAML 的应用领域
YAML 被广泛应用于各种领域,包括:
- 配置文件: YAML 是许多应用程序和工具的配置文件格式,如 Docker、Ansible、Kubernetes、Travis CI 等。
- 数据交换: YAML 可以用于系统之间的数据传输,特别是在 RESTful API 和微服务架构中。
- 文档生成: YAML 常用于定义文档结构,如 Jekyll 博客引擎中的前置元数据。
示例: YAML 配置文件
以下是一个 YAML 配置文件的示例,它定义了一个简单的博客网站的配置:
1 | site_name: My Awesome Blog |
接下来介绍一下语法:
基本语法
1. 大小写敏感
YAML 是大小写敏感的。这意味着
key
和Key
是两个不同的键。例如:
1
2name: John
Name: Doe在这个例子中,
name
和Name
被视为两个不同的键。
2. 使用缩进表示层级关系
- YAML 通过缩进来表示数据的层级结构。
- 子元素相对于父元素需要缩进。
- 缩进的层级代表数据的嵌套关系。
例如:
1
2
3
4
5
6person:
name: John Doe
age: 30
address:
city: New York
country: USA
在这个例子中:
name
,age
, 和address
是person
的子元素。city
和country
是address
的子元素。
3. 缩进规则
- 缩进不能使用 Tab 键,只能使用空格。
- 缩进的空格数量可以是任意的,但相同层级的元素必须左对齐,即使用相同数量的空格。
例如:
1
2
3
4
5
6
7correct_example:
first_level:
second_level: value
incorrect_example:
first_level:
second_level: value # 使用 Tab 键会导致错误
注意: 在不同层级之间,使用的空格数可以不同,但相同层级的元素必须对齐。
4. 注释
- 使用
#
来表示注释,#
后面的内容将被忽略。 - 注释可以放在单独一行,也可以放在数据行的后面。
例如:
1
2
3# 这是一个注释
name: John Doe # 这是行尾注释
age: 30 # 用户的年龄
在这个例子中:
# 这是一个注释
是一行完整的注释。# 这是行尾注释
和# 用户的年龄
是行尾注释。
5. 基本数据结构
键值对(Mappings): 使用冒号(
:
)分隔键和值。例如:
1
2name: John Doe
age: 30列表(Sequences): 使用连字符(
-
)表示列表项。例如:
1
2
3
4hobbies:
- reading
- swimming
- coding字面量块(Block Scalars): 使用
|
或>
表示多行字符串,其中|
保留换行符,>
折叠换行符。例如:
1
2
3
4
5
6
7description: |
这是一个多行字符串,
会保留换行符。
folded_text: >
这是一个多行字符串,
但换行符将被折叠为一个空格。
6. 文件后缀
- YAML 文件通常以
.yaml
或.yml
作为文件后缀。 .yml
是.yaml
的缩写,两者没有任何区别,使用哪种取决于个人或项目的约定。
7. 特殊值
- 布尔值: 可以使用
true
/false
或yes
/no
来表示布尔值。 - 空值: 可以使用
null
、~
或者省略冒号后的值来表示空值。
例如:
1
2
3
4is_admin: true
has_access: yes
not_set: null
empty_value:
8. 字符串表示
- 字符串可以不加引号,但为了避免歧义,可以使用单引号(
'
)或双引号("
)。 - 双引号支持转义字符,而单引号则不支持。
例如:
1
2
3
4plain_string: Hello World
quoted_string: "Hello, World!"
escaped_string: "Hello, \"World\""
single_quoted: 'It''s a great day!'
9. 多文档语法
- YAML 支持在同一个文件中包含多个文档,用
---
分隔。 - 每个文档可以包含独立的内容。
例如:
1
2
3
4
5
6
name: John Doe
age: 30
name: Jane Doe
age: 28
这表示两个独立的 YAML 文档。
数据类型
1. 对象(Objects)
对象是键值对的集合,也称为映射(mapping)、哈希(hashes)、或字典(dictionary)。对象在 YAML 中通常用于表示具有键值关系的数据结构,类似于 JSON 中的对象或 Python 中的字典。
表示方法:
- 使用冒号
:
将键和值分开。 - 每个键值对占一行,键和值之间用空格分隔。
- 对象的键是唯一的,不能重复。
例子:
1
2
3
4
5
6person:
name: John Doe
age: 30
address:
street: 1234 Elm Street
city: Springfield
解释:
person
是一个对象,包含多个键值对。name
和age
是简单的键值对。address
是一个嵌套的对象,包含street
和city
作为子键值对。
对象嵌套:
- 对象可以嵌套,即一个对象的值可以是另一个对象。
1
2
3
4
5company:
name: TechCorp
location:
city: New York
country: USA
在这个例子中,location
是 company
对象中的一个嵌套对象。
2. 数组(Arrays)
数组是一组按次序排列的值,也称为序列(sequence)或列表(list)。在 YAML 中,数组用于表示多个值的集合,这些值按照顺序排列,并且可以是任何类型的数据,包括对象、纯量或其他数组。
表示方法:
- 使用连字符
-
表示数组中的每个元素。 - 每个元素占一行,位于连字符后面,并且通常缩进两个空格。
例子:
1
2
3
4fruits:
- Apple
- Banana
- Orange
解释:
fruits
是一个数组,包含三个元素:Apple
、Banana
、Orange
。- 数组中的每个元素都是一个纯量。
数组嵌套:
- 数组可以包含其他数组或对象作为其元素。
1
2
3
4
5
6
7
8
9
10
11employees:
- name: John Doe
age: 30
skills:
- Python
- JavaScript
- name: Jane Smith
age: 25
skills:
- Java
- C++
在这个例子中,employees
是一个数组,包含两个对象。每个对象有一个 skills
数组。
3. 纯量(Scalars)
纯量是单个的、不可再分的值,表示最基本的数据信息。在 YAML 中,纯量可以是字符串、数字、布尔值或空值等。
表示方法:
- 纯量值可以直接写在键值对的冒号后面。
- 字符串可以不加引号,但为了避免歧义或保留特殊字符,可以使用单引号
'
或双引号"
。
例子:
1
2
3
4
5name: John Doe
age: 30
is_admin: true
description: "This is a description with special characters."
empty_value: null
解释:
name
是一个字符串类型的纯量。age
是一个数字类型的纯量。is_admin
是一个布尔类型的纯量,表示真值(true)。description
是一个带双引号的字符串,保留了特殊字符。empty_value
是一个空值(null),表示没有数据。
纯量的不同表示方法:
多行字符串: 使用
|
或>
表示多行字符串,其中|
保留换行符,>
折叠换行符。1
2
3
4
5
6multiline_text: |
This is a multi-line
string in YAML.
folded_text: >
This string will be folded
into a single line.解释:
multiline_text
使用|
表示多行字符串,每一行的换行符都会保留。folded_text
使用>
表示折叠字符串,换行符将被转换为空格。
- 对象 适用于表示键值对的结构化数据,是 YAML 中最常见的数据类型。
- 数组 用于表示有序的数据列表,常用于需要表达多个值的场景。
- 纯量 则用于表示单一的、不可再分的基本值,适合描述简单的数据元素。
引用
在 YAML
中,引用、锚点(&
)、和别名(*
)是强大的功能,用于简化和优化配置文件的结构,减少重复内容。以下是对这些概念的详细解释。
1. 锚点 (&
)
锚点用于创建一个可重用的内容块,赋予它一个名称(即锚点名)。锚点类似于为一段数据创建一个标签,之后可以在 YAML 文档的其他部分引用这段数据。
例子:
1 | defaults: |
解释:
&defaults
创建了一个锚点,名字为defaults
。- 这个锚点包含了两个键值对:
adapter: postgres
和host: localhost
。
2. 别名 (*
)
别名用于引用已经创建的锚点,并将锚点对应的内容插入到引用的位置。
例子:
1 | development: |
解释:
<<: *defaults
表示将defaults
锚点的内容合并到development
对象中。*defaults
是一个别名,指向之前定义的defaults
锚点。- 这意味着
development
中的内容将自动包含defaults
锚点中定义的所有键值对。
3. 合并 (<<
)
合并操作符 <<
用于将锚点的内容与当前的数据结构合并。在上面的例子中,<<: *defaults
将 defaults
锚点的内容合并到 development
对象中。
4. 综合例子
考虑以下 YAML 配置:
1 | defaults: |
解释:
defaults
锚点包含两个键值对:adapter: postgres
和host: localhost
。- 在
development
和test
中,使用<<: *defaults
引用并合并defaults
的内容。 - 因此,
development
和test
都将包含adapter: postgres
和host: localhost
,而不需要重复这些内容。
5. 等价展开
上述 YAML 经过展开后,相当于以下内容:
1 | defaults: |
解释:
development
和test
中包含了defaults
中的所有内容,并且在此基础上添加了各自的database
键值对。
6. 列表中的引用
锚点和别名不仅可以在映射(对象)中使用,还可以在序列(列表)中使用。
例子:
1 | - &showell Steve |
解释:
&showell Steve
创建了一个锚点showell
,其值为Steve
。- 在列表的最后一项,使用
*showell
来引用这个锚点,因此最后一项的值也是Steve
。
7. 等价展开
上面的 YAML 列表展开后等同于:
1 | [ 'Steve', 'Clark', 'Brian', 'Oren', 'Steve' ] |
解释:
- 列表中第一个和最后一个元素都是
Steve
,因为最后一个元素是通过引用锚点showell
得到的。
- 锚点 (
&
) 用于创建一个可重用的内容块。- 别名 (
*
) 用于引用锚点,并将锚点的内容插入到当前位置。- 合并 (
<<
) 用于将锚点的内容合并到当前的数据结构中。
示例
以下是一个复杂的 YAML 配置文件示例,适用于一个假设的博客系统。这个例子展示了如何使用 YAML 来配置博客的多个方面,包括站点设置、页面配置、导航菜单、社交链接、文章分类、标签和插件设置。
1 | # 博客基本设置 |
详细解释:
站点设置 (
site
): 配置博客的基本信息,如站点名称、描述、URL、作者姓名和语言。主题设置 (
theme
): 定义博客的主题相关配置,如主题名称、配色方案、字体、社交链接、Logo 和 Favicon。页面配置 (
pages
): 为博客的各个页面(如首页、关于页面、联系页面)配置具体内容和布局。导航菜单配置 (
menu
): 设置博客的导航菜单,包括菜单项的名称、链接和图标。文章分类配置 (
categories
): 定义博客文章的分类,每个分类都有一个名称、描述和颜色。标签配置 (
tags
): 定义博客文章的标签,每个标签都有一个名称和颜色。文章示例 (
posts
): 列出博客文章的示例,每篇文章包括标题、日期、作者、分类、标签和内容。插件配置 (
plugins
): 配置博客使用的插件,如 Google Analytics、SEO 插件和评论系统。自定义设置 (
custom
): 定义一些自定义的博客功能,如订阅弹窗、作者简介和暗模式支持。其他设置 (
misc
): 其他杂项设置,如时区、日期格式、时间格式、默认分类和是否显示相关文章。
与其他结合
YAML 是一种数据序列化格式,本身并不包含逻辑或功能。它的作用是用于配置和数据交换,其主要目的是将数据以结构化的方式表示,以便其他语言(如 Python、JavaScript、Ruby 等)能够读取和使用这些数据。因此,要让 YAML 配置文件真正发挥作用,需要将它与编程语言或框架结合使用。
1. 与 Python 结合
在 Python 中,可以使用 PyYAML
库来解析和读取 YAML
文件,并将其内容转换为 Python
的数据结构(如字典、列表)。这些数据可以在应用程序中用作配置或参数。
示例:
1 | import yaml |
2. 与 JavaScript 结合
在 Node.js 中,可以使用 js-yaml
库来解析 YAML
文件,将其转换为 JavaScript 对象。配置数据通常用于配置 Web
应用、构建工具或其他 JavaScript 项目。
示例:
1 | const yaml = require('js-yaml'); |
3. 与 Ruby on Rails 结合
在 Ruby on Rails 项目中,YAML 通常用作配置文件格式(如
database.yml
)。Rails 提供了内置支持,可以自动加载并解析
YAML 文件,将其内容应用于数据库连接等配置。
示例:database.yml
1 | default: |
在 Ruby on Rails 中,这个文件将用于配置不同环境下的数据库连接信息。
4. 与 CI/CD 工具结合
在持续集成/持续交付(CI/CD)工具(如 GitLab CI、Travis CI)中,YAML 文件通常用来定义流水线的步骤。工具会读取 YAML 配置并执行相应的任务。
示例:.gitlab-ci.yml
1 | stages: |
5. 与 Web 框架结合
在一些 Web 框架中,如 Jekyll 或 Hexo(静态网站生成器),YAML 文件通常用于前置数据(Front Matter)或全局配置。框架会读取这些 YAML 数据并根据配置生成 HTML 页面。
示例:Hexo 的 _config.yml
1 | title: My Awesome Blog |