当前位置: 欣欣网 > 码农

在 .NET中解析操作Yaml文件

2024-05-11码农


概述: 不幸的是,YAML 文件是当今所有开发人员日常生活的一部分;尽管它们非常容易出错,并且几乎不可能在没有 IDE 和架构信息的情况下进行编辑而不会经常遇到错误——向所有认为这是一个好主意的 CI 系统致以问候:事实并非如此——但我们必须接受我们必须处理它们的事实。在 .NET 中,YamlDotNet 库是处理 YAML 文件的常用选择。该库非常易于使用,并为大多数 YAML 文件提供了非常好的支持。处理 YAML 文件时,提供两种不同的选项:通过字典访问键值或反序列化为类。这两种方法都有其优点和缺点,但在大多数情况下,反序列化为类是更方便、更好的选择。YamlDotNet从 YAML 反序列化

不幸的是,YAML 文件是当今所有开发人员日常生活的一部分;尽管它们非常容易出错,并且几乎不可能在没有 IDE 和架构信息的情况下进行编辑而不会经常遇到错误——向所有认为这是一个好主意的 CI 系统致以问候:事实并非如此——但我们必须接受我们必须处理它们的事实。

在 .NET 中,YamlDotNet 库是处理 YAML 文件的常用选择。该库非常易于使用,并为大多数 YAML 文件提供了非常好的支持。

处理 YAML 文件时,提供两种不同的选项:通过字典访问键值或反序列化为类。这两种方法都有其优点和缺点,但在大多数情况下,反序列化为类是更方便、更好的选择。YamlDotNet

从 YAML 反序列化

对于类的反序列化,相应的类也是必需的;举个例子,我采用博客文章潜在标题的结构:

title: Handle Yaml Files with .NET
description: This blog post shows a simple sample how to serialize and deserialize yaml files with .NET
options:
isDraft: true
date: 2024-04-23T15:30:00Z
author:
name: BEN ABT
twitter: https://twitter.com/Abt_Benjamin
linkedIn: https://www.linkedin.com/in/benjaminabt/
job:
company: Medialesson GmbH
description: Chief PullRequest Officer
website: https://media-lesson.com/

因此,类结构可以 1:1 实现:

public classBlogPost
{
publicstring Title { get; set; } = null!;
publicstring Description { get; set; } = null!;
publicOptions Options { get; set; } = null!;
publicAuthor Author { get; set; } = null!;
publicstring Content { get; set; } = null!;
}
public classOptions
{
publicbool IsDraft { get; set; }
publicDateTimeOffset Date { get; set; }
}
public classAuthor
{
publicstring Name { get; set; } = null!;
publicstring Twitter { get; set; } = null!;
publicstring LinkedIn { get; set; } = null!;
publicJob Job { get; set; } = null!;
}
public classJob
{
publicstring Company { get; set; } = null!;
publicstring Description { get; set; } = null!;
publicstring Website { get; set; } = null!;
}

截至目前,YamlDotNet 不支持任何记录;反序列化程序需要一个类,该类在属性中具有空构造函数和相应的 setter。

反序列化非常简单:

IDeserializer deserializer = newDeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
// yamlBlogPost = string with yaml content
BlogPost blogPost = deserializer.Deserialize<BlogPost>(yamlBlogPost);

然后,该对象将 YAML 文件中的相应值作为实例包含在内,可以照常访问。blogPost

序列化为 YAML

序列化也同样简单,只是相反:

ISerializer serializer = newSerializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
string blogPostYaml = serializer.Serialize(blogPost);

完整示例

// --------------------------------------------------------------------
// This sample shows the handling of YAML files in .NET.
// The YamlDotNet library (https://github.com/aaubry/YamlDotNet) is used to serialize and deserialize YAML files.
// 2024-04-23 - https://schwabencode.com
// Runtime: .NET 8
// Sample Project: Console App
// Dependency: YamlDotNet
usingYamlDotNet.Serialization;
usingYamlDotNet.Serialization.NamingConventions;
// --------------------------------------------------------------------
// sample Yaml-File in style of a blog post header
string yamlBlogPost =
"""
title: Handle Yaml Files with .NET
description: This blog post shows a simple sample how to serialize and deserialize yaml files with .NET
options:
isDraft: true
date: 2024-04-23T15:30:00Z
author:
name: BEN ABT
twitter: https://twitter.com/Abt_Benjamin
linkedIn: https://www.linkedin.com/in/benjaminabt/
job:
company: Medialesson GmbH
description: Chief PullRequest Officer
website: https://media-lesson.com/
""";
// --------------------------------------------------------------------
// deserialize string as model
IDeserializer deserializer = newDeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
BlogPost blogPost = deserializer.Deserialize<BlogPost>(yamlBlogPost);
// Print blog post
Console.WriteLine(newstring('-', 30));
Console.WriteLine($"## Print Blog Post Object");
Console.WriteLine($"Title: {blogPost.Title}");
Console.WriteLine($"\tDescription: {blogPost.Description}");
Console.WriteLine($"Options");
Console.WriteLine($"\tIs Draft: {blogPost.Options.IsDraft}");
Console.WriteLine($"\tDate: {blogPost.Options.Date:o}");
Console.WriteLine($"Author");
Console.WriteLine($"\tName: {blogPost.Author.Name}");
Console.WriteLine($"\tTwitter: {blogPost.Author.Twitter}");
Console.WriteLine($"\tLinkedIn: {blogPost.Author.LinkedIn}");
Console.WriteLine($"\tJob");
Console.WriteLine($"\t\tCompany: {blogPost.Author.Job.Company}");
Console.WriteLine($"\t\tDescription: {blogPost.Author.Job.Description}");
Console.WriteLine($"\t\tWebsite: {blogPost.Author.Job.Website}");
// --------------------------------------------------------------------
// create yaml serializer with options
ISerializer serializer = newSerializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
string blogPostYaml = serializer.Serialize(blogPost);
Console.WriteLine(newstring('-', 30));
Console.WriteLine($"## Print Blog Post Text");
Console.WriteLine(blogPostYaml);
// --------------------------------------------------------------------
// sample models as classes, records are not supported today
public classBlogPost
{
publicstring Title { get; set; } = null!;
publicstring Description { get; set; } = null!;
publicOptions Options { get; set; } = null!;
publicAuthor Author { get; set; } = null!;
publicstring Content { get; set; } = null!;
}
public classOptions
{
publicbool IsDraft { get; set; }
publicDateTimeOffset Date { get; set; }
}
public classAuthor
{
publicstring Name { get; set; } = null!;
publicstring Twitter { get; set; } = null!;
publicstring LinkedIn { get; set; } = null!;
publicJob Job { get; set; } = null!;
}
public classJob
{
publicstring Company { get; set; } = null!;
publicstring Description { get; set; } = null!;
publicstring Website { get; set; } = null!;
}









PS:请不要使用Yaml,如果你没有必要的话。每个人都讨厌yaml。

如果你喜欢我的文章,请给我一个赞!谢谢