文章目錄
- 一、yaml簡介
- 二、YAML 文件基本語法
- 1.縮進
- 2.鍵值對
- 3.注釋
- 4.支持多種數據類型
- 5.示例 YML 文件
- 三、YAML 文件的基本元素:純量、對象、數組
- 1.純量(scalars)
- (1)布爾值(Booleans)
- (2)Null 值
- 2.對象(Object) / 映射(Mapping) / 字典(Dictionaries) / 鍵值對(Key-Value Pairs)
- 3.數組(Array) / 列表(Lists) / 序列(sequence)
- 4.復合結構 / 嵌套結構(Nested Structures)
- 5.多行字符串(Multi-line Strings)
- (1)字面量式 |
- (2)折疊式 >
- 四、實戰操作
- 1.安裝YAML
- 2.編譯
- 3.示例代碼
- (1)代碼1
- (2)代碼2:列表、try、catch
- (3)代碼3:嵌套列表
- (4)代碼4:列表中的字典
- (5)代碼5:多行字符串和列表
- (6)代碼6:列表中的混合數據類型
- (7)代碼7:列表中的復合數據
- 五、YAML的優缺點
- 六、YAML與其他格式的對比
一、yaml簡介
YAML(YAML Ain’t Markup Language)是一種標記語言,用于表示數據結構。它最初的目標是成為一種簡潔易讀的數據序列化格式,適用于配置文件、數據交換以及日志等應用。YAML 格式的最大特點是其語法非常簡潔、直觀,尤其適合用于人類閱讀和編輯。YAML 支持復雜的數據結構,如字典、列表、嵌套、引用等,因此非常適合用于描述結構化數據。
YAML(“YAML Ain’t Markup Language”)是一種以數據序列化為主的輕量級標記語言,因其語法簡潔、易讀性高而廣泛用于配置文件、數據交換和存儲。
YAML 文件使用 .yml
或 .yaml
擴展名
YAML 擁有 Perl、C、XML、HTML 和其他編程語言的特性。YAML 也是 JSON 的超集,所以 JSON 文件在 YAML 中有效。
相比 JSON,因為 YAML 有更好的可讀性,對用戶更友好,所以通常建議用 YAML 來編寫配置文件,盡管它們在大多數情況下可以互換使用。
二、YAML 文件基本語法
YAML 文件通常具有以下幾個特點:
1.縮進
YAML 使用空格進行縮進,表示層級關系,推薦使用兩個空格作為縮進單位(但是切勿使用制表符 (Tab),否則可能導致解析錯誤)。
- 大小寫敏感;
- 使用縮進表示層級關系;
- 縮進時不允許使用 Tab 鍵,只允許使用空格;
- 縮進的空格數目不重要,只要相同層級的元素左側對齊即可;
#
表示注釋:
號后面要加空格
2.鍵值對
YAML 中的每個數據項都是一個鍵值對,鍵和值之間用冒號:
分隔,冒號后跟一個空格
。
3.注釋
注釋用#
符號表示,注釋內容從 # 后開始,到行尾結束。【而json文件就不支持注釋】
4.支持多種數據類型
YAML 支持字符串、整數、浮動點數、布爾值、Null、日期等類型
5.示例 YML 文件
# 這是一個簡單的YML示例
server:host: localhost # 服務器地址port: 8080 # 端口號database:name: mydbuser: adminpassword: secret123tables:- users- orders- productsenabled: true
三、YAML 文件的基本元素:純量、對象、數組
YAML 的基本數據結構只有三種:純量(Scalar)、映射(Mapping) 和 序列(Sequence),分別對應單個值、有序列表和鍵值對集合:
①純量:最基本的,不可再分的值;
②對象:mapping/hash/dictionary:鍵值對的集合;
③數組:sequence/list:一組按次序排列的值;數組和對象可以構成復合結構;
1.純量(scalars)
純量是最基本的、不可再分的值。
以下數據類型都屬于 JavaScript 的純量:
- 字符串
- 布爾值
- 整數
- 浮點數
- null:用 ~ 表示
- 時間
- 日期
boolean: - TRUE #true,True都可以- FALSE #false,False都可以
float:- 3.14- 6.8523015e+5 #可以使用科學計數法
int:- 123- 0b1010_0111_0100_1010_1110 #二進制表示
null:nodeName: 'node'parent: ~ #使用~表示null
string:- 哈哈- 'Hello world' #可以使用雙引號或者單引號包裹特殊字符- newlinenewline2 #字符串可以拆成多行,每一行會被轉化成一個空格
date:- 2018-02-17 #日期必須使用ISO 8601格式,即yyyy-MM-dd
datetime: - 2018-02-17T15:02:31+08:00 #時間使用ISO 8601格式,時間和日期之間使用T連接,最后使用+代表時區
(1)布爾值(Booleans)
布爾值可以用 true 或 false 來表示,YAML 還允許使用 yes、no、on、off 等值來表示布爾類型。
is_active: true
is_enabled: yes
(2)Null 值
null 值可以使用 null 或 ~ 來表示。
value1: null
value2: ~
2.對象(Object) / 映射(Mapping) / 字典(Dictionaries) / 鍵值對(Key-Value Pairs)
YAML 中最基本的元素是鍵值對,格式為 key: value
(1)鍵值對:
name: John Doe
age: 30
(2)對象:
key: child-key: valuechild-key2: value2
(3)字典:
字典是由多個鍵值對組成的集合。在 YAML 中,字典的嵌套通過縮進來表示。
person:name: John Doeage: 30address:street: 123 Main Stcity: New Yorkzip: 10001
3.數組(Array) / 列表(Lists) / 序列(sequence)
YAML 使用 - 符號來表示列表項。每個列表項占據一行,且列表項之間通過換行分隔。
以 - 開頭的行表示構成一個數組:
fruits:- Apple- Orange- Banana
4.復合結構 / 嵌套結構(Nested Structures)
YAML 通過縮進表示嵌套結構。可以在字典中嵌套列表,在列表中嵌套字典,或者在字典中嵌套其他字典。
team:- name: Alicerole: Developerskills:- Python- JavaScript- name: Bobrole: Designerskills:- Photoshop- Sketch
languages:- Ruby- Perl- Python
websites:YAML: yaml.org Ruby: ruby-lang.org Python: python.org Perl: use.perl.org
5.多行字符串(Multi-line Strings)
YAML 支持多行字符串的表示,有兩種方式:字面量式(literal style) 和 折疊式(folded style)。
(1)字面量式 |
字面量式:用 | 表示,將多行文本保留原格式,換行會被保留。
description: |This is a long descriptionthat spans multiple lines,and it will be preserved asmultiple lines in the output.
(2)折疊式 >
折疊式:用 > 表示,將多行文本折疊成一個字符串,換行會被替換為空格。
description: >This is a long descriptionthat spans multiple lines,but it will be collapsed into asingle line.
四、實戰操作
1.安裝YAML
sudo apt-get install libyaml-cpp-dev
2.編譯
編譯要加連接選項:-lyaml-cpp
,即
g++ read_yaml.cpp -o read_yaml -lyaml-cpp
3.示例代碼
(1)代碼1
config.yaml
name: MyYAML
version: 0.1
description: "A simple YAML configuration file"
enabled: true
read_yaml.cpp
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>
using std::cout;
using std::endl;
using std::string;int main() {// 讀取 YAML 文件YAML::Node config = YAML::LoadFile("config.yaml");// 讀取配置項string name = config["name"].as<string>(); // 獲取 'name' 字段double version = config["version"].as<double>(); // 獲取 'version' 字段string description = config["description"].as<string>(); // 獲取 'description' 字段bool enabled = config["enabled"].as<bool>(); // 獲取 'enabled' 字段// 輸出配置項cout << "Name: " << name << endl;cout << "Version: " << version << endl;cout << "Description: " << description << endl;cout << "Enabled: " << std::boolalpha << enabled << endl;return 0;
}
(2)代碼2:列表、try、catch
config2.yaml
#基本的列表結構
fruits:- Apple- Banana- Orange
不帶try-catch的版本:
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>using namespace std;int main() {// 打開并加載 YAML 文件YAML::Node config = YAML::LoadFile("config2.yaml");// 讀取 fruits 列表YAML::Node fruits = config["fruits"];if (fruits) {// 遍歷 fruits 列表for (const auto& fruit : fruits) {cout << fruit.as<string>() << endl;}} else {cout << "No 'fruits' node found in the YAML file." << endl;}return 0;
}
帶 try-catch的版本:
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>using namespace std;int main() {try {// 打開并加載 YAML 文件YAML::Node config = YAML::LoadFile("config2.yaml");// 讀取 fruits 列表YAML::Node fruits = config["fruits"];if (fruits) {// 遍歷 fruits 列表for (const auto& fruit : fruits) {cout << fruit.as<string>() << endl;}} else {cout << "No 'fruits' node found in the YAML file." << endl;}} catch (const YAML::Exception& e) {cerr << "Error reading YAML file: " << e.what() << endl;return 1;}return 0;
}
(3)代碼3:嵌套列表
#嵌套列表
employees:- name: Alicerole: Developerskills:- Python- JavaScript- name: Bobrole: Designerskills:- Photoshop- Illustrator
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>using namespace std;int main() {// 打開并加載 YAML 文件YAML::Node config = YAML::LoadFile("config3.yaml");// 讀取 employees 列表YAML::Node employees = config["employees"];if (employees) {// 遍歷 employees 列表for (const auto& employee : employees) {cout << "Name: " << employee["name"].as<string>() << endl;cout << "Role: " << employee["role"].as<string>() << endl;// 讀取技能列表YAML::Node skills = employee["skills"];cout << "Skills: ";for (const auto& skill : skills) {cout << skill.as<string>() << " ";}cout << endl << endl;}} else {cout << "No 'employees' node found in the YAML file." << endl;}return 0;
}
(4)代碼4:列表中的字典
#列表中的字典
tasks:- name: Task 1completed: false- name: Task 2completed: true- name: Task 3completed: false
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>using namespace std;int main() {// 打開并加載 YAML 文件YAML::Node config = YAML::LoadFile("config4.yaml");// 讀取 tasks 列表YAML::Node tasks = config["tasks"];if (tasks) {// 遍歷 tasks 列表for (const auto& task : tasks) {cout << "Task Name: " << task["name"].as<string>() << endl;cout << "Completed: " << (task["completed"].as<bool>() ? "Yes" : "No") << endl;cout << endl;}} else {cout << "No 'tasks' node found in the YAML file." << endl;}return 0;
}
(5)代碼5:多行字符串和列表
#多行字符串和列表
description: |This is a multiline string.It will preserve the newlinesexactly as they are written.
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>using namespace std;int main() {// 打開并加載 YAML 文件YAML::Node config = YAML::LoadFile("config5.yaml");// 讀取 description 多行字符串YAML::Node description = config["description"];if (description) {// 輸出多行字符串cout << "Description:\n" << description.as<string>() << endl;} else {cout << "No 'description' node found in the YAML file." << endl;}return 0;
}
(6)代碼6:列表中的混合數據類型
#列表中的混合數據類型
data:- 42- "Hello"- true- { key: value }- [1, 2, 3]
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>using namespace std;int main() {// 打開并加載 YAML 文件YAML::Node config = YAML::LoadFile("config6.yaml");// 讀取 data 列表YAML::Node data = config["data"];if (data) {// 遍歷 data 列表for (const auto& item : data) {// 判斷數據類型并輸出if (item.IsScalar()) {// 如果是標量類型(如整數、字符串、布爾值)cout << "Scalar: " << item.as<string>() << endl;} else if (item.IsMap()) {// 如果是字典(Map)cout << "Map: " << endl;for (const auto& pair : item) {cout << " " << pair.first.as<string>() << ": " << pair.second.as<string>() << endl;}} else if (item.IsSequence()) {// 如果是列表(Sequence)cout << "Sequence: ";for (const auto& elem : item) {cout << elem.as<int>() << " "; // 假設元素是整數類型}cout << endl;}}} else {cout << "No 'data' node found in the YAML file." << endl;}return 0;
}
(7)代碼7:列表中的復合數據
#列表中的復合數據
projects:- name: Project 1description: "This is the first project."tasks:- task1- task2- name: Project 2description: "This is the second project."tasks:- task3- task4
#include <iostream>
#include <fstream>
#include <yaml-cpp/yaml.h>using namespace std;int main() {// 打開并加載 YAML 文件YAML::Node config = YAML::LoadFile("config7.yaml");// 讀取 projects 列表YAML::Node projects = config["projects"];if (projects) {// 遍歷 projects 列表for (const auto& project : projects) {// 輸出項目的基本信息cout << "Project Name: " << project["name"].as<string>() << endl;cout << "Description: " << project["description"].as<string>() << endl;// 讀取 tasks 列表YAML::Node tasks = project["tasks"];if (tasks) {cout << "Tasks: ";// 遍歷任務列表for (const auto& task : tasks) {cout << task.as<string>() << " ";}cout << endl;}cout << endl;}} else {cout << "No 'projects' node found in the YAML file." << endl;}return 0;
}
五、YAML的優缺點
缺點:
①YAML對縮進敏感,一般是兩個空格作為縮進
②解析速度比json慢