.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分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

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

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

Search

Popular

reccomended

Categories

Tags