C#とXnaでxmlファイルを読み込むにはSystem.xml内のクラスをを使う事もできますが、xnaにはコンテントパイプラインを使い、xmlの読み込みと書き込みをほぼ自動に行う機能が付いているので、それについてメモります。
*注意:大熊猫は英語版のVisual Studio 2010を使っているので、説明と画像には英語の部分が偶にあります。
コンテントパイプラインを使ってのxml操作は、IntermediateSerializerを使うと楽に出来ます。IntermediateSerializerには、xmlの書き込み時に自動的にオブジェクトの内容をコンテントパイプラインに合わせた書き方をしてくれるという利点があります。読み込み時にも、最短1行で読み込めると言う利点があります。
IntermediateSerializerを使うにはまず、プロジェクトにMicrosoft.Xna.Content.Pipelineを足す必要が有ります(プロジェクト内の参照を右クリックして ”Add Reference…”を選択)。もし.NETのタブ内に見つからない場合、dllを直接探して足してください(私の場合はC:\Program Files\Microsoft XNA\XNA Game Studio\v4.0\References\Windows\x86 に有りました)。
Dllを足したら、プロジェクトのプロパティを開き、「アプリケーション」のタブ内で、”Target Platform”を “.Net Framework 4 Client Profile” から”.Net Framework 4”に変更してください。この設定を変更しないとIntermediateSerializerを使えないので、必ず変えてください。
プロジェクトの設定を変更し終えたら、まずxmlに保存するクラスを書きます。
class Person { public Vector2 Position; public string Name; int m_id; public Person() { this.Position = Vector2.Zero; this.Name = ""; this.m_id = -1; } public Person(Vector2 position, string name, int id) { this.Position = position; this.Name = name; this.m_id = id; } public int ID { get { return m_id; } set { m_id = value; } } //-----ココから保存されない------// public int GetOnlyID { get { return m_id; } } public int SetOnlyField { set { } } }
xmlに保存するクラスには幾つか注意するところがあります:
– 必ずパラメーター無しのコンストラクタが必要
– メンバ変数は、Public設定以外は保存されない
– アクセサはGetとSetの両方がある場合のみ、保存される
次は実際にxmlファイルにPersonクラスのインスタンスを保存します:
string fileName = "test.xml"; string filePath = System.IO.Directory.GetCurrentDirectory() + "\\" + fileName; Person person = new Person(new Vector2(100.0f, 25.0f), "Ookumaneko", 100); System.Xml.XmlWriterSettings setting = new System.Xml.XmlWriterSettings(); setting.Indent = true; using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(fileName, setting)) { // xmlファイルに書き込む IntermediateSerializer.Serialize<Person>(writer, person, filePath); }
これでIntermediateSerializer.Serializeメソッドの第3引数で設定したパスにxmlファイルが作られます:
<?xml version="1.0" encoding="utf-8"?> <XnaContent> <Asset Type="XmlTest.Person"> <ID>100</ID> <Position>100 25</Position> <Name>Ookumaneko</Name> </Asset> </XnaContent>
次は書き込んだxmlファイルの読み込みです。これには二つの方法が有ります。まずはIntermediateSerializerを使用した方法です:
string fileName = "test.xml"; string filePath = System.IO.Directory.GetCurrentDirectory() + "\\" + fileName; Person person; System.Xml.XmlReaderSettings setting = new System.Xml.XmlReaderSettings(); using (System.Xml.XmlReader reader = System.Xml.XmlReader.Create(filePath, setting)) { // xmlを読み込み、保存する person = IntermediateSerializer.Deserialize<Person>(reader, null); }
次はコンテントパイプラインを使用し、テクスチャアなどの読み込みと同じ方法です。この方法を使うには、プロジェクト上のコンテントプロジェクトにxmlファイルの追加してください。この方法を使用しての読み込みをするには、コンテントプロジェクトに読み込むクラスがあるプロジェクトに参照を通す必要が有ります。その際、プロジェクトが一つしかない場合、コンテントパイプラインとゲームプロジェクトがお互いを参照しあう事になるので、新たなプロジェクトを作る必要が有ります。(もっと楽な方法があるかただいま検索中・・・)
Person person = Content.Load<TestLib.Person>("test.xml");
テストプロジェクト:
http://www.mediafire.com/download.php?a40q8t24ae2uszj