.net column

.NET開発者のためのブログメディア

C#でXMLをシリアライズする方法を分かりやすく解説!

2020年08月20日
SE
XMLのシリアライズとは一体なんでしょうか?
PM
XMLファイルを作成することをシリアライズと呼びます。では詳しくみていきましょう。

C#でXMLをシリアライズする方法をわかりやすく解説

C#によるXMLのシリアライズとは?

現在のソフトウェア開発において、XMLファイルは多くのシステムで使用されています。XMLファイルを作成することをシリアライズ、XMLファイルを読み込むことをデシリアライズと言います。C#でそれを行うにはどうしたら良いのでしょうか。

この記事ではまずXMLとは何か、という基本的なところから、C#でXMLをシリアライズ・デシリアライズする方法を分かりやすく解説します。XML初心者の方は是非ご覧ください。

XMLとは何か

XMLとは以下のように<と>を使用したテキストファイルのフォーマットのことです。<と>の部分はタグと言います。Webページを記述する時に使うHTMLに似ています。

<ramen>
<men>太麺</men>
<soup>しょうゆ味</soup>
<gu>
<vegetable>ねぎ</vegetable>
<meat>チャーシュー</meat>
<egg>半熟味玉</egg>
</gu>
</ramen>

XMLのシリアライズ

以下のC#のサンプルは、上のラーメンのXMLをシリアライズします。

using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;

namespace ConsoleApp1
{
[XmlRoot(“”ramen””)] public class Ramen
{
public Ramen()
{
// コンストラクタでGuのインスタンスを一緒に生成
Gu = new Gu();
}

[XmlElement(“”men””)] public string Men { get; set; }

[XmlElement(“”soup””)] public string Soup { get; set; }

[XmlElement(“”gu””)] public Gu Gu { get; set; }
};

[XmlRoot(“”gu””)] public class Gu
{
[XmlElement(“”vegetable””)] public string Vegetable { get; set; }

[XmlElement(“”meat””)] public string Meat { get; set; }

[XmlElement(“”egg””)] public string Egg { get; set; }
};

class Program
{
static void Main(string[] args)
{
var ramen = new Ramen();

ramen.Men = “”太麺””;
ramen.Soup = “”しょうゆ味””;
ramen.Gu.Vegetable = “”ねぎ””;
ramen.Gu.Meat = “”チャーシュー””;
ramen.Gu.Egg = “”半熟味玉””;

var xs = new XmlSerializer(typeof(Ramen));
using (var sw = new StreamWriter(“”c:\\test\\ramen.xml””, false, Encoding.UTF8))
{
xs.Serialize(sw, ramen);
}
}
}
}

属性でタグの名前を指定できる

上のC#のサンプルを順に説明しましょう。まず、RamenとGuというクラスを定義しています。[XmlRoot(“”~””)]と[XmlElement(“”~””)]という属性を記述していますが、これによりXMLにシリアライズした時のタグの名前を指定できます。

属性で指定しない場合は、クラス名のRamenやプロパティ名のMenがそのまま使われます。ただしXMLのタグ名は先頭が小文字なことが通例なので、このように属性を使って変更しているのです。

XmlSerializerでシリアライズする

Mainメソッドでは、まずRamenクラスを生成しています。この時コンストラクタが呼ばれてRamen内部のGuのインスタンスも生成されます。

そしてMenなどのプロパティに文字列を代入しています。次にXmlSerializerクラスをRamenクラスを指定して生成し、using内でファイル書き込みを行うStreamWriterを生成します。StreamWriterの引数にはファイル名・追記するかどうか=false・文字エンコード=UTF8を指定しています。

usingを使用して安全にシリアライズできる

usingは{と}で囲った処理が終わった後に、後始末をしてくれるC#の機能です。このようなファイル制御で使用すればファイルのclose処理を自動的に行ってくれます。

{と}の中では、XmlSerializerに生成したRamenクラスとStreamWriterクラスを渡して、Serializeでシリアライズを行います。このC#サンプルを実行すればcドライブのtestフォルダにramen.xmlが作成されます。

デシリアライズのサンプル

次は、C#でXMLファイルをデシリアライズする(読み込む)方法を説明します。ここまでのC#サンプルの、Mainメソッドを以下のように書き換えましょう。

static void Main(string[] args)
{
var xs = new XmlSerializer(typeof(Ramen));
Ramen ramen;
using (var sr = new StreamReader(“”c:\\test\\ramen.xml””, Encoding.UTF8))
using (var xr = System.Xml.XmlReader.Create(sr))
{
ramen = (Ramen)xs.Deserialize(xr); // Ramenクラスにキャストする
}
Console.WriteLine(ramen.Men);
Console.WriteLine(ramen.Gu.Egg);
}

XmlReaderでデシリアライズできる

上のC#サンプルを実行すると、以下のように表示されます。

太麺
半熟味玉

XmlSerializer・StreamReader・XmlReaderを使用することでramen.xmlをデシリアライズして、Ramenクラスのインスタンスとして読み込めていることがわかります。

XMLElementクラスでシリアライズ

ここまでのC#サンプルのRamenクラスのような、独自のクラスを作らずにXMLをシリアライズする場合はどうすればよいのでしょうか。その場合はXMLElementが便利です。Mainメソッドを以下のように書き換えてください。また「using System.Xml;」の追加も必要となります。

static void Main(string[] args)
{
XmlDocument xd = new XmlDocument();
XmlElement ramen = xd.CreateElement(“”ramen””);
XmlElement men = xd.CreateElement(“”men””);
men.InnerXml = “”太麺””;
ramen.AppendChild(men);
XmlElement gu = xd.CreateElement(“”gu””);
XmlElement egg = xd.CreateElement(“”egg””);
egg.InnerXml = “”半熟味玉””;
gu.AppendChild(egg);
ramen.AppendChild(gu);

XmlSerializer xr = new XmlSerializer(typeof(XmlElement));
using (var sw = new StreamWriter(“”c:\\test\\ramen.xml””, false, Encoding.UTF8))
{
xr.Serialize(sw, ramen);
}
}

AppendChildメソッドで追加が可能

上を実行するとramen.xmlファイルが生成されます。その中身は以下のようになります。

<ramen>
<men>太麺</men>
<gu>
<egg>半熟味玉</egg>
</gu>
</ramen>

XmlElementのAppendChildメソッドでXMLのツリー構造が実現できています。

XmlElementにデシリアライズ

XMLファイルをXmlElementの型にデシリアライズすることもできます。サンプルのMainメソッドを以下のように書き換えてください。

static void Main(string[] args)
{
var xs = new XmlSerializer(typeof(XmlElement));
XmlElement ramen;
using (var sr = new StreamReader(“”c:\\test\\ramen.xml””, Encoding.UTF8))
using (var xr = System.Xml.XmlReader.Create(sr))
{
ramen = (XmlElement)xs.Deserialize(xr); // Ramenクラスにキャストする
}
Console.WriteLine(ramen.InnerXml);
}

独自クラスを使わずデシリアライズできる

上のサンプルを実行すると、
<men>太麺</men>
<gu>
<egg>半熟味玉</egg>
</gu>

と表示されます。XmlElement型のインスタンスとして取りこめていることがわかります。

SE
HTMLに似ていますが、もっと効率的な方法なんですね。
PM
その分奥の深い仕様ですが是非マスターして活用していきましょう。

C#のシリアライズでXMLを活用しよう

この記事でC#のXMLの扱いの基礎が理解できたのではないでしょうか。XMLには色々な仕様があり奥が深いですが、その分覚えれば大きく差がつきます。是非マスターしてXMLを活用してください。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

求人一覧

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)