C#でXMLの読み書きをしてみた
C#でXMLを読み書きしてみました。XmlSerializerを使う方法です。 このサイト を思いっきり参考にしました。
この投稿の実施例は、下記環境のものです。
Visual Studio Express 2015 for Windows Desktop (C#)
Windows 8.1
目次
どうやってデータを格納するか
データ格納用のクラスを作るのですが、XMLの構造に合わせる必要があります。以下、注意点です。
XMLの構造に合わせたクラスを作る。
子ノードが複数ある場合は、親ノード用のクラスに設定する子ノード用プロパティをコレクションにする。
クラスとそのプロパティの属性でXMLの要素名を指定する。
逆シリアル化したときに、要素に値が無くてもエラーにならない。
シリアル化したときに、値が無い要素は書き出さない。
処理の流れ
XMLの読み込みと書き出しは、ざっくりと下記の流れになります。
読み込み
読み込むファイルを指定してファイルストリームを開く。
XmlSerializer()コンストラクターでシリアライザーのインスタンスを作る。
XmlSerializer.Deserialize()メソッドで逆シリアライズしてオブジェクトへ格納する。
書き出し
ファイルストリームを開いて、ストリームライターのインスタンスを作る。
XmlSerializerNamespacesクラスのインスタンスを作る。
XmlSerializerNamespaces.Add()メソッドでXML名前空間の値を設定する。
XmlSerializer()コンストラクターでシリアライザーのインスタンスを作る。
XmlSerializer.Serialize()メソッドで、オブジェクトをXMLにする。
ストリームライターでストリームをファイルに書き込む。
試してみた
文章で説明するよりコードを見た方が早いかもしれません。XMLファイルを読み込んで、逆シリアル化したデータをコンソールに表示し、そのデータをさらにシリアル化してファイルに保存する、コンソールアプリを作ってみます。
読み込むXMLファイル
例として、下記のXMLデータを読み込んでみることにします。ファイル名はtest.xmlにします。
<?xml version="1.0" encoding="utf-8"?>
<company>
<person id="01">
<name>まどか</name>
<color>ピンク</color>
</person>
<person id="02">
<name>ほむら</name>
<color>黒</color>
<nickname>ほむほむ</nickname>
</person>
<person id="03">
<name>さやか</name>
<color>青</color>
</person>
</company>
ニックネームの設定がある人が一人しかいないですね。
クラス
ルートノード(company)用のクラスを下記のようにします。
namespace xml_trial
{
[System.Xml.Serialization.XmlRoot("company")]
public class Company
{
// XMLファイル内にcompany要素直下のperson要素が複数あるので、プロパティをコレクションにする。
[System.Xml.Serialization.XmlElement("person")]
public System.Collections.Generic.List<xml_trial.Person> Person { get; set; }
}
}
personノードが複数あるので、List型のコレクションにしました。
子ノード(person)用のクラスを下記のようにします。
namespace xml_trial
{
public class Person
{
[System.Xml.Serialization.XmlAttribute("id")]
public String ID { get; set; }
[System.Xml.Serialization.XmlElement("name")]
public String Name { get; set; }
[System.Xml.Serialization.XmlElement("color")]
public String Color { get; set; }
[System.Xml.Serialization.XmlElement("nickname")]
public String NickName { get; set; }
}
}
属性はXmlAttribute、内容はXmlElementで取り出しですね。
処理
読み書き部分のコードは下記のようにしました。上述の流れに沿ってます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Xml.Serialization;
namespace xml_trial
{
class Program
{
static void Main(string[] args)
{
// 読み込み
FileStream inputStream = new FileStream(@"test.xml", FileMode.Open); // ファイルストリームのインスタンスを作る。
XmlSerializer serializer = new XmlSerializer(typeof(xml_trial.Company)); // シリアライザーのインスタンスを作る。
xml_trial.Company model = (xml_trial.Company)serializer.Deserialize(inputStream); // 逆シリアライズしてオブジェクトに格納する。
// 読み込んだデータの表示
foreach (xml_trial.Person person in model.Person)
{
Console.WriteLine(String.Format("ID={0}, Name={1}, NickName={2}, Color={3}", person.ID, person.Name, person.NickName, person.Color));
}
// 書き出し
FileStream outputStream = new FileStream("export.xml", FileMode.Create); // ファイルストリームのインスタンスを作る。
StreamWriter writer = new StreamWriter(outputStream, Encoding.UTF8); // ストリームライターのインスタンスを作る。
XmlSerializerNamespaces outputNameSpace = new XmlSerializerNamespaces();// XML名前空間のインスタンスを作る。
outputNameSpace.Add(String.Empty, String.Empty); // XML名前空間の値を設定する。
XmlSerializer outputSerializer = new XmlSerializer(typeof(xml_trial.Company)); // シリアライザーのインスタンスを作る。
outputSerializer.Serialize(writer, model,outputNameSpace); // オブジェクトをシリアライズしてストリームへ。
writer.Flush(); // ストリームをファイルに書き込む。
writer.Close(); // ストリームを閉じる。
}
}
}
ファイルストリームを使うのでSystem.IOを、XMLシリアライザー用にSystem.Xml.Serializationをusingに追加しました。
実行してみた
プロジェクトをビルドして、実行してみました。
要素にデータが無くても、エラーも出さずに読み込んでますね。XML出力結果は下記になりました。
<?xml version="1.0" encoding="utf-8"?>
<company>
<person id="01">
<name>まどか</name>
<color>ピンク</color>
</person>
<person id="02">
<name>ほむら</name>
<color>黒</color>
<nickname>ほむほむ</nickname>
</person>
<person id="03">
<name>さやか</name>
<color>青</color>
</person>
</company>
データの無い要素は出力されてませんね。希望通りの出力になりました。
公開日
広告