C#/.NET 序列化和反序列化 YAML 元数据

项目中需要将Yaml文件反序列化为自定义的强类型对象进而对其内容进行修改。

这里参考https://blog.walterlv.com/post/serialize-and-deserialize-yaml.html

.NET 并没有原生提供对 YAML 的序列化和反序列化。虽然 YAML 文件的解析并不难,不过如果不是处于特别的理由(比如性能),使用现有的库解析 YAML 是比较好的选择。


本文推荐使用 YamlDotNet 序列化和反序列化 YAML。

本文内容

YAML 元数据

作为示例,我拿出我在去年写的一篇博客的元数据进行分析:

layout: post
title: "利用 TypeConverter,转换字符串和各种类型只需写一个函数"
date_published: 2017-01-17 18:13:00 +0800
date: 2018-04-23 07:31:32 +0800
categories: dotnet
permalink: /dotnet/2017/01/17/convert-using-type-converter.html
keywords: dotnet typeconverter
description: 使用 TypeConverter 实现字符串转各种类型。

注意,实际上元数据是包含开始标签和结束标签的。yaml 元数据以 --- 包裹,toml 元数据以 +++ 包裹。

由于从 Markdown 中解析出 YAML 元数据不是本文的重点,所以我放到最后一起说明。

定义 .NET 类型

我们需要先定义 .NET 类型,以便 YamlDotNet 进行序列化和反序列化。

public sealed class YamlFrontMeta
{
    [YamlMember(Alias = "title", ApplyNamingConventions = false)]
    public string Title { get; set; }

    [YamlMember(Alias = "date", ApplyNamingConventions = false)]
    public string Date { get; set; }

    [YamlMember(Alias = "date_published", ApplyNamingConventions = false)]
    public string PublishDate { get; set; }

    [YamlMember(Alias = "layout", ApplyNamingConventions = false)]
    public string Layout { get; set; }

    [YamlMember(Alias = "permalink", ApplyNamingConventions = false)]
    public string PermanentUrl { get; set; }

    [YamlMember(Alias = "categories", ApplyNamingConventions = false)]
    public string Categories { get; set; }

    [YamlMember(Alias = "tags", ApplyNamingConventions = false)]
    public string Tags { get; set; }

    [YamlMember(Alias = "keywords", ApplyNamingConventions = false)]
    public string Keywords { get; set; }

    [YamlMember(Alias = "description", ApplyNamingConventions = false)]
    public string Description { get; set; }

    [YamlMember(Alias = "versions", ApplyNamingConventions = false)]
    public List<VersionsInfo> Versions { get; set; }

    [YamlMember(Alias = "published", ApplyNamingConventions = false)]
    public bool IsPublished { get; set; } = true;

    [YamlMember(Alias = "sitemap", ApplyNamingConventions = false)]
    public bool IsInSiteMap { get; set; } = true;
}

.NET 类型中的属性必须是 YAML 文件中属性的超集。

以上 ApplyNamingConventions 属性的默认值是 true,这为了解决一些命名约束上的问题,详见:YamlMember Alias isn’t applied when using the CamelCaseNamingConvention · Issue #228 · aaubry/YamlDotNet

另外,如果 YAML 属性中包含数组,则需要将属性的类型设置为集合类型。

title: "Good Framework Rely on Good Api —— Six API Design Principles"
date_published: 2018-06-30 19:09:53 +0800
date: 2018-08-12 16:04:26 +0800
categories: dotnet framework
versions:
  - 中文: /post/framework-api-design.html
  - English: #
public sealed class VersionInfo
{
    [YamlMember(Alias = "current", ApplyNamingConventions = false)]
    public string Current { get; set; }
}

public sealed class VersionsInfo
{
    [YamlMember(Alias = "中文", ApplyNamingConventions = false)]
    public string Chinese { get; set; }

    [YamlMember(Alias = "English", ApplyNamingConventions = false)]
    public string English { get; set; }
}

序列化与反序列化

使用 Deserializer 类型可以反序列化一个 YAML 元数据。

var deserializer = new Deserializer();
var matter = deserializer.Deserialize<YamlFrontMeta>(yamlText);

使用 Serializer 类型可以序列化一个 YAML 元数据到字符串。这样,就能更新博客的 YAML 元数据部分了。

var serializer = new Serializer();
var yamlText = serializer.Serialize(matter);
YAMLYAML Ain't Markup Language)是一种人类可读的数据序列化格式,它被广泛用于配置文件、数据交换和文档等场景中。序列化是将复杂的数据结构转换为 YAML 格式的过程,而反序列化则是从 YAML 格式恢复数据到原始数据结构的过程。 **序列化教程:** 1. **安装库**:许多编程语言都有支持 YAML 序列化的库,比如 Python 的 PyYAML,JavaScript 的 `js-yaml` 等。确保你已经安装了对应的库。 2. **Python 示例**: ```python import yaml data = { 'name': 'John', 'age': 30, 'city': 'New York' } # 序列化 serialized_data = yaml.dump(data) print(serialized_data) # 输出:name: John age: 30 city: New York # 反序列化 deserialized_data = yaml.safe_load(serialized_data) print(deserialized_data) # 输出:{'name': 'John', 'age': 30, 'city': 'New York'} ``` 3. **保存和读取文件**:你可以选择将序列化后的数据保存到文件,然后在需要时读取并反序列化。 **反序列化教程:** 1. **处理结构复杂的对象**:YAML 通常能很好地处理嵌套的数据结构,如列表和字典。 2. **错误处理**:如果 YAML 文件格式错误或解析失败,需要捕获异常进行错误处理。 3. **跨语言支持**:如果你的应用涉及多个编程语言,了解不同语言如何处理 YAML 反序列化也是必要的。 **相关问题--:** 1. YAML 序列化和 JSON 序列化有什么区别? 2. 在 JavaScript 中如何进行 YAML序列化反序列化? 3. 如何处理 YAML 文件中的注释和特殊字符?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值