C#でXMLファイルを読み書きする①

皆様あけましておめでとうございます。からすぱんです。

いやぁ、寒いですね。年明け早々に大寒波が訪れ、ゲレンデはとっても良いコンディションのようですが、、今年は雪山観光もあきらめる他ありません。とっても残念です。

さて、今回はC#でXMLファイルを扱う際に便利なXmlSerializerクラスの使い方について、数回に分けて書きたいと思います。


XmlSerializerクラスとは

オブジェクトから XML ドキュメントへのシリアル化および XML ドキュメントからオブジェクトへの逆シリアル化を実行します。 XmlSerializer により、オブジェクトを XML にエンコードする方法を制御できます。

https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.serialization.xmlserializer?view=net-5.0

XMLファイルを読み込んだり、作成する際に使えるんだろうということがわかるかと思います。

今回は、デシリアライズ(読み込み)から解説していきたいと思います。


XmlSerializerでXMLファイルを読み込む

まずは読み込むXMLファイルを用意します。

<?xml version="1.0"?>
  <XmlData Key="Test">
    <Name>name</Name>
    <Id>1</Id>
  </XmlData>

次に、XMLをデシリアライズしたデータを格納するクラスオブジェクトを作成します。その際、下記のルールに従って作成する必要があります。

  • クラスオブジェクトがpublicな場所にあること
  • クラスオブジェクト自体がpublicであること
  • デシリアライズ/シリアライズするフィールド、プロパティはpublicであること
  • プロパティにXMLのタブカテゴリ(属性名、要素名等)を指定すること(指定がない場合はデフォルトでプロパティ名が要素として適応される)
/// <summary>
/// XMLに格納する1つのデータ要素を格納する
/// </summary>

public class XmlData
{

    /// <summary>
    /// Key属性
    /// </summary>
    [XmlAttribute("Key")]
    public string Key { get; set; }

    /// <summary>
    /// 名前要素
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// ID要素
    /// </summary>
    public int Id { get; set; }
}

今回はKeyプロパティが属性となりますので、「XmlAttribute」を付けています。そのほか要素には「XmlElement」、ルート要素には「XmlRoot」等を指定することができますが、詳細は次回解説していきたいと思います。

最後にデシリアライズします。

string filePath = @"C:\sample.xml";
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
    XmlSerializer serializer = new XmlSerializer(typeof(XmlData));
    var data = serializer.Deserialize(fs) as XmlData;

    Console.Write("{0}: {1}, {2}: {3}, {4}: {5}", "Key", data.Key, "Name", data.Name, "Id", data.Id);
  Console.Read();
}

デシリアライズにはXmlSerializer.Deserializeメソッドを使います。

今回はFileStreamクラスを用いてストリーム化したXMLファイルデータをDeserializeメソッドに渡し、その後先ほど作成した格納クラスにキャストしています。

出力結果:

Key: Test, Name: name, Id: 1

無事に読み込むことができました。

なお、Keyプロパティの[XmlAttribute(“Key”)]を削除すると、下記のような結果になります。

Key: , Name: name, Id: 1

Key属性の値が出力されませんでした。これは、属性、要素、リスト等特にプロパティにカテゴリの指定がない場合はデフォルトで要素として扱われるためです。「Key要素」はXMLファイルに存在しないため、値は代入されません。

いかがだったでしょうか。

今回はデシリアライズの方法について簡単に解説してみました。

次回はシリアライズと、プロパティのカテゴリ指定の詳細について解説していきたいと思います。