当前位置: 首页 > news >正文

配置文件 yaml

文章目录

  • 一、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: mydb
  user: admin
  password: secret123
  tables:
    - users
    - orders
    - products

enabled: 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'  #可以使用双引号或者单引号包裹特殊字符
    - newline
      newline2    #字符串可以拆成多行,每一行会被转化成一个空格
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: value
    child-key2: value2

(3)字典:
字典是由多个键值对组成的集合。在 YAML 中,字典的嵌套通过缩进来表示。

person:
  name: John Doe
  age: 30
  address:
    street: 123 Main St
    city: New York
    zip: 10001

3.数组(Array) / 列表(Lists) / 序列(sequence)

YAML 使用 - 符号来表示列表项。每个列表项占据一行,且列表项之间通过换行分隔。

以 - 开头的行表示构成一个数组:

fruits:
  - Apple
  - Orange
  - Banana

4.复合结构 / 嵌套结构(Nested Structures)

YAML 通过缩进表示嵌套结构。可以在字典中嵌套列表,在列表中嵌套字典,或者在字典中嵌套其他字典。

team:
  - name: Alice
    role: Developer
    skills:
      - Python
      - JavaScript
  - name: Bob
    role: Designer
    skills:
      - 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 description
  that spans multiple lines,
  and it will be preserved as
  multiple lines in the output.

(2)折叠式 >

折叠式:用 > 表示,将多行文本折叠成一个字符串,换行会被替换为空格。

description: >
  This is a long description
  that spans multiple lines,
  but it will be collapsed into a
  single 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: Alice
    role: Developer
    skills:
      - Python
      - JavaScript
  - name: Bob
    role: Designer
    skills:
      - 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 1
    completed: false
  - name: Task 2
    completed: true
  - name: Task 3
    completed: 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 newlines
  exactly 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 1
    description: "This is the first project."
    tasks:
      - task1
      - task2
  - name: Project 2
    description: "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慢



六、YAML与其他格式的对比

在这里插入图片描述

相关文章:

  • Unity2D:从零开始制作一款跑酷游戏!
  • 【第2月 day16】Matplotlib 散点图与柱状图
  • 第四课:模型的概念及应用
  • 【trino】trino配置证书https tls/ssl访问
  • Git -> git pull --rebase 遇到error : Filename too long的临时解决方案
  • LTSPICE仿真电路:(二十五)低侧电流检测电路仿真
  • 在WPF中使用VisualCollection创建复杂Adorner详解
  • AI Agent成为行业竞争新焦点:技术革新与商业重构的双重浪潮
  • 数据库事务与锁的知识点
  • Axure RP9.0教程: 查询条件隐藏与显示(综合了动态面板状态切换及展开收缩效果实现)
  • 管家婆财贸ERP BB100.采购单返写估价入库单价
  • On Superresolution Effects in Maximum Likelihood Adaptive Antenna Arrays论文阅读
  • PyTorch深度学习框架 的基础知识
  • Java高频面试题2:集合框架
  • Vue3 Pinia Store 新建store示例、使用store示例
  • 配置文件 ini
  • 一周学会Pandas2 Python数据处理与分析-编写Pandas2 HelloWord项目
  • 人脸识别和定位别的签到系统
  • python发送qq邮件
  • 开源模型应用落地-Qwen2.5-Omni-7B模型-部署 “光速” 指南