< メモ: WPF アプリケーションのローカライズ方法 | メモ: スレッド処理 >

November 6, 2008

XmlSerializer を使う (シリアル化編)

System.Xml.Serialization 名前空間に XmlSerializer というクラスがある。その名のとおり、データを XML 形式でシリアル化してくれるというもの。

シリアル化するクラスは public でないといけないらしい。クラスメンバについても public なプロパティや変数が対象になる。メソッドは対象とならない。また、get/set の両方が可能である必要がある。

また、デフォルトコンストラクタのないクラスは扱えない。メンバにも含めることが出来ない。

// 性別
public enum GenderEnum : int { Male, Female, }

// ありがちなクラス
public class Person
{
    public string Name { get; set; }
    public GenderEnum Gender { get; set; }
    public DateTime Birthday { get; set; }
    public int Age { get; set; }
}

上記 Person クラスのシリアライズはこんな感じ。

using System;
using System.Linq;

class XmlSerializeSample
{
    static void Main ()
    {
        // 名前生成用w
        var suffix = new string [] { "郎", "子" };

        // Person の配列を作る
        var people = Enumerable.Range (0, 5)
            .Select (index => new { index = index, day = new DateTime (1975 + index, index + 1, index + 1) })
            .Select (param => new Person ()
            {
                Name = string.Format ("{0:ddd}", param.day) + suffix [param.index % 2],
                Gender = (GenderEnum) (param.index % 2),
                Birthday = param.day,
                Age = DateTime.Now.Year - param.day.Year    // 年齢が適当ですね…
            }).ToArray ();

        // XmlSerializer を使用したシリアライズ
        var serializer = new System.Xml.Serialization.XmlSerializer (typeof (Person []));
        var stream = new System.IO.StreamWriter("C:\\people.xml", false);
        serializer.Serialize(stream, people);
        stream.Close();
    }
}

出力結果はこんな感じ。

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfPerson xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Person>
    <Name>水郎</Name>
    <Gender>Male</Gender>
    <Birthday>1975-01-01T00:00:00</Birthday>
    <Age>33</Age>
  </Person>
  <Person>
    <Name>月子</Name>
    <Gender>Female</Gender>
    <Birthday>1976-02-02T00:00:00</Birthday>
    <Age>32</Age>
  </Person>
  <!-- 中略 -->
</ArrayOfPerson>

配列をシリアル化したので、ルート要素が“ArrayOfPerson”となっていた。これは変更が可能。

// ルート要素を People に
var serializer = new System.Xml.Serialization.XmlSerializer (typeof (Person []), new System.Xml.Serialization.XmlRootAttribute("People"));

出力結果。

<?xml version="1.0" encoding="utf-8"?>
<People xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Person>
  <!-- 中略 -->
  </Person>
</People>

デフォルトでは、すべてのメンバが要素として出力されるが、テキストノード、あるいはアトリビュートとして扱うことも可能。

using System;
using System.Xml.Serialization;

// クラス宣言に属性を追加
public class Person
{
    [XmlText]
    public string Name { get; set; }
    [XmlAttribute]
    public GenderEnum Gender { get; set; }
    [XmlAttribute]
    public DateTime Birthday { get; set; }
    [XmlAttribute]
    public int Age { get; set; }
}
<?xml version="1.0" encoding="utf-8"?>
<People xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Person Gender="Male" Birthday="1975-01-01T00:00:00" Age="33">水郎</Person>
  <Person Gender="Female" Birthday="1976-02-02T00:00:00" Age="32">月子</Person>
  <Person Gender="Male" Birthday="1977-03-03T00:00:00" Age="31">木郎</Person>
  <Person Gender="Female" Birthday="1978-04-04T00:00:00" Age="30">火子</Person>
  <Person Gender="Male" Birthday="1979-05-05T00:00:00" Age="29">土郎</Person>
</People>

トラックバック

このエントリーにトラックバック:
http://frog.raindrop.jp/cgi-bin/mt/mt-tb.cgi/2229

コメント

コメントする

※ コメントスパム対策のため、コメント本文はおはよう、こんにちわ、こんばんわのいずれかより始めるようにしてください。

name:
email:

※ 必要ですが、表示しません。

url:
情報を保存する ?