ZetCode

C# YAML

最后修改时间 2025 年 5 月 1 日

本文介绍了如何使用 YamlDotNet 库在 C# 中使用 YAML 格式。

理解 YAML

YAML (YAML Ain't Markup Language) 是一种人类友好的数据序列化格式,广泛用于配置文件、数据存储(例如,调试输出)和数据传输(例如,文档头)。

它原生支持三种基本数据类型

YAML 文件通常使用 .yaml 扩展名,这是官方推荐的格式。

在 .NET 中使用 YAML

YamlDotNet 库允许 .NET 开发人员高效地解析和序列化 YAML 数据。 要安装该包,请运行以下命令

$ dotnet add package YamlDotNet

安装后,可以将该库集成到您的项目中以处理基于 YAML 的数据结构。

C# YamlStream

YamlStream 允许我们通过流读取 YAML 数据。

Program.cs
using YamlDotNet.RepresentationModel;

string doc = @"
cities:
  - Bratislava
  - Kosice
  - Trnava
  - Moldava
  - Trencin
name: John Doe
occupation: gardener";


using var sr = new StringReader(doc);

var yaml = new YamlStream();
yaml.Load(sr);

var root = (YamlMappingNode) yaml.Documents[0].RootNode;

foreach (var e in root.Children)
{
    Console.WriteLine(e);
    Console.WriteLine($"{e.Key} {e.Value}");
}

Console.WriteLine("------------------------------");

Console.WriteLine(root["name"]);
Console.WriteLine(root["occupation"]);
Console.WriteLine(root["cities"]);

在该示例中,我们使用 YamlStream 从字符串中读取 YAML。

string doc = @"
cities:
    - Bratislava
    - Kosice
    - Trnava
    - Moldava
    - Trencin
name: John Doe
occupation: gardener";

这是在 C# 字符串中定义的 YAML 数据。

using var sr = new StringReader(doc);

var yaml = new YamlStream();
yaml.Load(sr);

我们将字符串传递给 StringReader。 然后使用 LoadStringReader 加载到 YamlStream

var root = (YamlMappingNode) yaml.Documents[0].RootNode;

我们获取文档的根节点。

foreach (var e in root.Children)
{
    Console.WriteLine(e);
    Console.WriteLine($"{e.Key} {e.Value}");
}

我们迭代根节点的子节点。 每个节点都有一个键和值。

Console.WriteLine(root["name"]);
Console.WriteLine(root["occupation"]);
Console.WriteLine(root["cities"]);

这是访问键的另一种方式。

$ dotnet run 
[cities, [ Bratislava, Kosice, Trnava, Moldava, Trencin ]]
cities [ Bratislava, Kosice, Trnava, Moldava, Trencin ]
[name, John Doe]
name John Doe
[occupation, gardener]
occupation gardener
------------------------------
John Doe
gardener
[ Bratislava, Kosice, Trnava, Moldava, Trencin ]

YAML 文档

YAML 文档用 --- 分隔。

data.yaml
name: Document 1
cities:
  - Bratislava
  - Kosice
  - Trnava
  - Moldava
  - Trencin
---
name: Document 2
companies:
  - Eset
  - Slovnaft
  - Duslo Sala
  - Matador Puchov

我们在 YAML 文件中有两个文档。

Program.cs
using YamlDotNet.RepresentationModel;

string data = File.ReadAllText("data.yaml");
using var sr = new StringReader(data);

var yaml = new YamlStream();
yaml.Load(sr);

int n = yaml.Documents.Count;

for (int i = 0; i < n; i++)
{
    var root = (YamlMappingNode)yaml.Documents[i].RootNode;
    foreach (var e in root.Children)
    {
        Console.WriteLine($"{e.Key} {e.Value}");
    }

    Console.WriteLine("-------------------------------");
}

该程序使用 YamlStream 读取两个文档。

string data = File.ReadAllText("data.yaml");

我们使用 File.ReadALlText 将数据从文件读取到字符串中。

int n = yaml.Documents.Count;

我们使用 Count 获取文档的数量。

for (int i = 0; i < n; i++)
{
    var root = (YamlMappingNode)yaml.Documents[i].RootNode;
    foreach (var e in root.Children)
    {
        Console.WriteLine($"{e.Key} {e.Value}");
    }

    Console.WriteLine("-------------------------------");
}

我们迭代文档的子节点。

$ dotnet run 
name Document 1
cities [ Bratislava, Kosice, Trnava, Moldava, Trencin ]
-------------------------------
name Document 2
companies [ Eset, Slovnaft, Duslo Sala, Matador Puchov ]

序列化数据

YAML 序列化是将 C# 对象转换为 YAML 字符串的过程。 这是通过 SerializerBuilder 完成的。

Program.cs
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

var users = new List<User>
{
    new ("John Doe", "gardener") ,
    new ("Roger Roe", "driver") ,
    new ("Valeria Smith", "teacher"),
};

var serializer = new SerializerBuilder()
    .WithNamingConvention(CamelCaseNamingConvention.Instance)
    .Build();
var yaml = serializer.Serialize(users);

Console.WriteLine(yaml);


record User(string Name, string Occupation);

该程序将 User 对象列表转换为 YAML 字符串。

var serializer = new SerializerBuilder()
    .WithNamingConvention(CamelCaseNamingConvention.Instance)
    .Build();

我们创建 SerializerBuilder 并对其进行配置。

var yaml = serializer.Serialize(users);

我们使用 Serialize 方法序列化数据。

$ dotnet run 
- name: John Doe
  occupation: gardener
- name: Roger Roe
  occupation: driver
- name: Valeria Smith
  occupation: teacher

反序列化数据

反序列化是将 YAML 字符串转换为 C# 对象的过程。

users.yaml
- Name: John Doe
  Occupation: gardener
- Name: Roger Roe
  Occupation: driver
- Name: Valeria Smith
  Occupation: teacher

我们在 users.yaml 文件中有一个用户列表。

Program.cs
using YamlDotNet.Serialization;

var deserializer = new DeserializerBuilder()
     .Build();

using var sr = File.OpenText("users.yaml");
List<User> users = deserializer.Deserialize<List<User>>(sr);

foreach (var user in users)
{
    Console.WriteLine(user);
}

class User
{
    public string? Name { get; set; }
    public string? Occupation { get; set; }

    public override string ToString()
    {
        return $"{this.Name} {this.Occupation}";
    }
}

在该程序中,我们从文件中读取数据并将其反序列化为 User 对象列表。

$ dotnet run 
John Doe gardener
Roger Roe driver
Valeria Smith teacher

来源

YamlDotNet Github 页面

在本文中,我们探讨了如何使用 YamlDotNet 库在 C# 中使用 YAML 格式。 通过利用其功能,开发人员可以高效地在 .NET 应用程序中解析、序列化和管理 YAML 数据。

作者

我的名字是 Jan Bodnar,我是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程