YamlSerializer for .NET

English version is here.

何をするためのライブラリですか?

主に2つの目的で使うことができます。
  • C# のオブジェクトをそのまま YAML テキストにシリアライズ・デシリアライズすることができます。(多くの場合こちらが便利です) => YamlSerizlizer クラス
  • 内部の構造が不明だったり、C# のクラスに対応しないカスタムデータタグを含むような一般の YAML ファイルを扱うこともできます。(こちらが必要になるケースは少ないかもしれません) => YamlNode クラス

動作環境

.NET 3.5 Sp1 で作成しました。

YAML とは何ですか?

YAML は XML よりも読みやすく、書きやすく、JSON よりも型にうるさく、しかも自由度がある、Ruby 使い達に人気の(?) データ記述形式です。

Rubyist Magazine YAML のわかりやすい解説 があります。

厳密な言語の定義は、The Official YAML Web Site を見て下さい。

YamlSerizlizer クラス

1つ目の目的には、YamlSerizlizer クラスの SerializeDeserialize メソッドを使います。これらのメソッドは C# のネイティブオブジェクトを、何の準備も無しに YAML text に変換することができます.

詳しくは YamlSerizlizer を見て下さい.

// 何の変哲もない object の配列です。
object obj = new object[]{ 
    "a", 
    true, 
    1, 
    1.0, 
    new Point(1,3), 
    new YamlScalar("node") 
};

var serializer = new YamlSerializer();

// 上記の配列をいきなり YAML にすることができます。
string yaml = serializer.Serialize( obj );

// 生成される YAML は次のような物です。
// 一目で内容が分かる点が XML と異なるところですね。

// %YAML 1.2
// ---
// - "a"
// - true
// - 1
// - !!float 1
// - !System.Drawing.Point 1,3
// - !YamlSerializer.YamlScalar
//   Tag: "tag:yaml.org,2002:str"
//   Value: "node"
// ...

// 読み出しも簡単です。
object restored = serializer.Deserialize(yaml)[0];

// 一般に1つの YAML ストリームには複数のオブジェクトを
// 保存することができるので、Deserialize の戻り値は配列に
// なっています。

YamlNode クラス

2つ目の目的のためには、YamlNode クラスと、その子クラス(YamlScalar, YamlSequence, YamlMapping)を使って YAML のデータノードを表すことになります。

ある YAML ファイルの中の構造が不明で、しかも C# のクラスに対応しないカスタムデータタグを含んでいる場合、そのようなファイルを YamlSerializer は読み込めません。YamlNode はそのような場合に対応するため、YAML ファイルを扱う非常に汎用的な方法を提供します。ただし、YamlNode を使う場合には Node を C# データに変換する作業をユーザー側で行わなければならないため、コード的には面倒になります。YamlSerializer を問題なく使える場合には、そちらを使うことをお勧めします。

スタティックメソッド YamlNode.FromYaml を使って任意の YAML テキストから YamlNode を読み出したり、YamlNodeToYaml メソッドで YAML テキストに変換したりすることができます.

詳しくは YamlNode を見て下さい。

// YAML のノードツリーを作成します。
// C# の文字列や整数、浮動小数点数を直接書き並べるだけで、
// 正しく型付けされた YamlNode が生成されます。
YamlNode node = 
    new YamlSequence(                           // !!seq ノード
        "abc",                                  // !!str ノード
        123,                                    // !!int ノード
        1.23,                                   // !!float ノード
        new YamlSequence(                       // ネストした !!seq ノード
            "def",
            "ghi"
        ),
        new YamlMapping(                        // !!map ノード
            "key1", "value1",
            "key2", "value2",
            "key3", new YamlMapping(            // ネストした !!map ノード
                "value3key1", "value3value1"
            ),
            "key4", "value4"
        )
    );

// YAML に変換します
string yaml = node.ToYaml();

// %YAML 1.2
// ---
// - abc
// - 123
// - 1.23
// - - def
//   - ghi
// - key1: value1
//   key2: value2
//   key3:
//     value3key1: value3value1
//   key4: value4
// ...

// YAML からノードを取り出します。
// 一般に、YAML ストリームには複数の YAML ドキュメントが含まれており、
// それぞれの YAML ドキュメントに1つのルート YAML ノードが含まれているので、
// 変換結果は YamlNode の配列になります。

YamlNode[] nodes = YamlNode.FromYaml(yaml);

// ここでは配列に含まれるただ1つのノードが上で保存した物です。
Assert.AreEqual(1, nodes.Length);
YamlNode resotred = nodes[0];

// 内容が等しいことを確認します。
Assert.AreEquel(node, restored);

// サブノードを取り出します。
var seq = (YamlSequence)restored;
var map = (YamlMapping)seq[4];
var map2 = (YamlMapping)map["key3"];

// 読み出したノードツリーの一部を変更します。
map2["value3key1"] = "value3value1 modified";

// 変更により2つのノードツリーは等しくなくなります。
Assert.AreNotEquel(node, restored);

Last edited Jul 19, 2013 at 1:17 AM by osamu, version 7

Comments

No comments yet.