ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

C# XMLへの階層構造の保存メモ1(基本編)

C#XMLファイルに親・子・孫‥といった階層構造を書き込みたい場合についてのメモです。

そもそもXMLを初めて扱うので基礎的なあたりを解説している記事を探して参考にしたのですが、こちらがとても入門として分かりやすくてオススメです。


という訳で試してみました。
Windowsフォームアプリでボタンをテキストボックスを配置。

f:id:moko_03_25:20190609152105j:plain

中身はこちらのように記述。
自分でも理解しやすいように、学校>クラス>名前と住所‥という内容にしました。
using System.Xml.Linq;」を先頭に追加するのをお忘れなく。。

private void Button1_Click(object sender, EventArgs e)
{
	XmlSave();
}

public void XmlSave()
{
	// XMLのヘッダー情報
	XDeclaration ヘッダー = new XDeclaration("1.0", "utf-8", "yes");
	// XMLの内容の定義
	XDocument xml = new XDocument(ヘッダー);

	// 学校の要素を定義
	XElement 学校;
	// <私立ほにゃ高校>タグを作成
	学校 = new XElement("私立ほにゃ高校");

	// 学校の要素をxmlに追加(これがRootになる)
	xml.Add(学校);

	// クラスの要素を定義
	XElement クラス;

	// <一組>タグを作成
	クラス = new XElement("一組");
	// <一組>タグに<名前>タグと<住所>タグをデータ込みでぶら下げる
	クラス.Add(new XElement("名前", "石坂"));
	クラス.Add(new XElement("住所", "静岡"));
	// Root(つまり学校)にぶら下げる
	xml.Root.Add(クラス);

	// <二組>タグを作成
	クラス = new XElement("二組");
	// <二組>タグに<名前>タグと<住所>タグをデータ込みでぶら下げる
	クラス.Add(new XElement("名前", "太郎"));
	クラス.Add(new XElement("住所", "福岡"));
	// Root(つまり学校)にぶら下げる
	xml.Root.Add(クラス);

	// TextBox1に表示
	textBox1.Text = xml.Declaration.ToString();
	textBox1.Text = xml.ToString();
}

 実行してbutton1を押すとtextBox1にバッチリ表示されました!

f:id:moko_03_25:20190609152112j:plain

ただし、実際にはもうちょっと複雑な構造‥例えばこんな感じにしたいですよね。

学校
 クラス
  先生
   名前
  生徒
   名前
  生徒
   名前
 クラス
  先生
   名前
  生徒
   名前


この場合はこちらのように記述すればOKです。

private void Button1_Click(object sender, EventArgs e)
{
	XmlSave();
}

public void XmlSave()
{
	// XMLの内容の定義
	var xml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));

	// 構造ごとの要素を定義
	XElement 学校;
	XElement クラス;
	XElement 先生;
	XElement 生徒;

	// <私立ほにゃ高校>タグを作成してxmlに追加
	学校 = new XElement("私立ほにゃ高校");
	xml.Add(学校);

	// <クラス>タグを作成してRoot(つまり学校)に追加
	クラス = new XElement("クラス");
	xml.Root.Add(クラス);
	// <先生>タグを作成して名前をぶら下げてから<クラス>タグに追加
	先生 = new XElement("先生");
	先生.Add(new XElement("名前", "浅野先生"));
	クラス.Add(先生);
	// <生徒>タグを作成して名前をぶら下げてから<クラス>タグに追加 * 人数分
	生徒 = new XElement("生徒1");
	生徒.Add(new XElement("名前", "飯尾"));
	クラス.Add(生徒);
	生徒 = new XElement("生徒2");
	生徒.Add(new XElement("名前", "上田"));
	クラス.Add(生徒);

	// <クラス>タグを作成してRoot(つまり学校)に追加
	クラス = new XElement("クラス");
	xml.Root.Add(クラス);
	// <先生>タグを作成して名前をぶら下げてから<クラス>タグに追加
	先生 = new XElement("先生");
	先生.Add(new XElement("名前", "江原先生"));
	クラス.Add(先生);
	// <生徒>タグを作成して名前をぶら下げてから<クラス>タグに追加 * 人数分
	生徒 = new XElement("生徒1");
	生徒.Add(new XElement("名前", "大谷"));
	クラス.Add(生徒);

	// XMLファイルに保存する
	xml.Save(@"sample.xml");

	// TextBox1に表示
	textBox1.Text = xml.Declaration.ToString();
	textBox1.Text = xml.ToString();
}

実行してみると、うまくいきました!

f:id:moko_03_25:20190609161443j:plain

躓いた点が一つあったのですが、<クラス>タグの定義の部分を「クラス = new XElement("クラス", "一組");」といったように値を入れてしまうと、階層構造が崩れました。子をぶら下げる箱として用意する場合には値を入れたらダメなんですかね。。

続きはこちら