WebMatrix/ASP.NET Web Pages で YAML を扱う

執筆日時:

ちょっと YAML を使いたいなーというシーンがあったので、いろいろ調べたみた。

YAML って?

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

ほんとう? それを確かめるためにちょっと比較してみました。例は XMLの論考: YAMLはXMLに改良を加える のものをベースに、XML-JSON相互変換ツール - Bluehawk's lab. で作成した JSON 形式のものを追加してあります。

XML で表現した場合

<?xml version="1.0"?>
<club>
<players>
<player id="kramnik"
            name="Vladimir Kramnik"
            rating="2700"
            status="GM" />
<player id="fritz"
            name="Deep Fritz"
            rating="2700"
            status="Computer" />
<player id="mertz"
            name="David Mertz"
            rating="1400"
            status="Amateur" />
</players>
<matches>
<match>
<Date>2002-10-04</Date>
<White refid="fritz" />
<Black refid="kramnik" />
<Result>Draw</Result>
</match>
<match>
<Date>2002-10-06</Date>
<White refid="kramnik" />
<Black refid="fritz" />
<Result>White</Result>
</match>
</matches>
</club>

タグがウザい。何でもできるけれど、少し厳格すぎるきらいがある。

JSON で表現した場合

{
"club": {
"players": {
"player": [
{
"-id": "kramnik",
"-name": "Vladimir Kramnik",
"-rating": "2700",
"-status": "GM"
},
{
"-id": "fritz",
"-name": "Deep Fritz",
"-rating": "2700",
"-status": "Computer"
},
{
"-id": "mertz",
"-name": "David Mertz",
"-rating": "1400",
"-status": "Amateur"
}
]
},
"matches": {
"match": [
{
"Date": "2002-10-04",
"White": { "-refid": "fritz" },
"Black": { "-refid": "kramnik" },
"Result": "Draw"
},
{
"Date": "2002-10-06",
"White": { "-refid": "kramnik" },
"Black": { "-refid": "fritz" },
"Result": "White"
}
]
}
}
}

ネストが深い。JavaScript との相性が抜群だが、いろいろユルい部分も多い。

YAML で表現した場合

---
players:
Vladimir Kramnik: &kramnik
rating: 2700
status: GM
Deep Fritz: &fritz
rating: 2700
status: Computer
David Mertz: &mertz
rating: 1400
status: Amateur
matches:
-
Date: 2002-10-04
White: *fritz
Black: *kramnik
Result: Draw
-
Date: 2002-10-06
White: *kramnik
Black: *fritz
Result: White

タグがないし、ネストも深くないのでスッキリ。ただ、構造化データを記述する以外の用途には向かない。

あと、参照の仕組み(アンカーとエイリアス、アドレスとポインタのようなもの)をもっているのがいい。これって、データベースをテキストに書きだしたり、オブジェクトをシリアライズするときにも便利だよね。

YamlSerializer for .NET

主に2つの目的で使うことができます。

  • C# のオブジェクトをそのまま YAML テキストにシリアライズ・デシリアライズすることができます。=> YamlSerizlizer クラス
  • 一般の YAML ファイルを扱うこともできます。 => YamlNode クラス

というわけで、今日はこのライブラリを使ってみる。ちゃんと NuGet にもパッケージングされていて、WebMatrix からもサックリ使えるよ。

f:id:daruyanagi:20121007113028p:plain

サンプルコード

# Default.cshtml

@functions { // シリアライズ・デシリアライズのためのサンプルクラス public class Person { public string FirstName { get; set; } public string LastName { get; set; }

public override string ToString() { return string.Format("{0} {1}", FirstName, LastName); } } }

@{ var person = new Person() { FirstName = "Hidetoshi", LastName = "Yanagi", };

// シリアライザの生成 // using System.Yaml.Serialization; var serializer = new YamlSerializer();

// YML形式のテキスト string yml =@" LastName:FirstName: 英俊 ";

// YMLテキスト → Person var deserialised = serializer.Deserialize( yml, typeof(Person) ); }

<!DOCTYPE html>

<html lang="ja"> <head> <meta charset="utf-8" /> <title>マイ サイトのタイトル</title> </head> <body> <pre> @serializer.Serialize(person) //<– YMLテキストに! </pre>

// 返り値は object 配列だよ! <h1>フルネームは @(deserialised[0] as Person) です。</h1> </body> </html>

結果

f:id:daruyanagi:20121007113045p:plain

ちょっとアレだな、とおもったのは @(deserialised[0] as Person) の部分だけれど、dynamic でうければいいのかもしれない。

dynamic deserialised = serializer.Deserialize(
yml, typeof(Person)
)[0];

deserialised.FirstName;