前回、PHP で YAML を操作したんですが、今回は、.NET C# でYAMLを操作したいと思います。
# 準備
まず、ツールの Nuget パッケージマネージャーから、YAMLDotNet パッケージをインストールします。記事を書いているときは、バージョン 16.3.0 が最新でした。
GitHub リポジトリ
https://github.com/aaubry/YamlDotNet
# YAML を読み込む
ネットで YamlDotNet の記事を探してみると、YAML構造をクラス化して読み書きするコードについてのサンプルはいくつか見つけられたのですが、構造を固定されていないと、クラスに定義されていない値などを読み込むとエラーになってしまいます。
例えば、こういう構造のYAMLを読み込む場合、
title: たいとる
values:
no1: 数字1
no2: 数字2
以下のようなクラスを定義して、YAMLを読み込む方法があります。今回は、クラスを定義して読み込む方法は説明しません。あくまで、ご参考。// YAMLのトップレベル要素に対応するクラス
public class MyYamlConfig
{
public string Title { get; set; } // 'title' に対応
public MyValues Values { get; set; } // 'values' に対応
}
// 'values' ネストされた要素に対応するクラス
public class MyValues
{
public string No1 { get; set; } // 'no1' に対応
public string No2 { get; set; } // 'no2' に対応
}
このクラスを定義する方法で、読み込むと、タイプミスなど確実に検出できるので、そういう用途が都合いいケースもあると思いますが、今回は、YAML の構造が可変であっても読み書きできるようにしたいと思います。
具体的には、YAML を Dictionary 構造に読み込みます。
var deserializer = new DeserializerBuilder()
.Build();
using (var reader = new StringReader(File.ReadAllText("coonfig.yaml")))
{
var config = deserializer.Deserialize<Dictionary<string, object>>(reader);
}
こだけで読み込み完了です。各要素には、以下のようにアクセスできます。子要素も、Dictionary として扱われます。Console.WriteLine($"タイトル: {config["title"]}");
if (config["values"] is Dictionary<object, object> values)
{
Console.WriteLine($"数字1: {values["no1"]}");
Console.WriteLine($"数字2: {values["no2"]}");
}
データを書き換えるには、、、config["title"] = "新しいタイトル";
if (config["values"] is Dictionary<object, object> valuesToUpdate)
{
valuesToUpdate["no1"] = "更新された数字1";
valuesToUpdate["no2"] = "更新された数字2";
}
キーを追加する場合config["description"] = "これは説明です。";
# 書き込み最後に、config の値を、ファイルに書き出します。
var serializer = new SerializerBuilder()
.ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull) // Null値のプロパティを出力しない
.Build();
using (var writer = new StringWriter())
{
serializer.Serialize(writer, config); // DictionaryをYAMLとしてシリアライズ
File.WriteAllText("config.yaml", writer.ToString());
}
というわけで、前回のPHPの記事を、C# で書いた場合の記事を書いてみました。