前回に続き、今度は実践編ということで元々やりたかったことを再帰処理で行ってみます。
フォームはこんな感じ。
あらかじめTreeViewに適当に孫以上の深い階層を追加しておきます。

実装はこんな感じ。
「using System.Xml.Linq;」を先頭に追加するのをお忘れなく。。
private void Form1_Load(object sender, EventArgs e)
{
treeView1.ExpandAll();
}
private void Button1_Click(object sender, EventArgs e)
{
XmlSave();
}
private void XmlSave()
{
var xml = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));
XElement Sample = new XElement("サンプル");
xml.Add(Sample);
TreeNodeCollection nodes = treeView1.Nodes;
foreach (TreeNode node in nodes)
{
XElement n = new XElement("ルートノード");
xml.Root.Add(n);
XmlRecursive(node, n);
}
textBox1.Text = xml.Declaration.ToString();
textBox1.Text = xml.ToString();
}
private void XmlRecursive(TreeNode node, XElement n)
{
XElement name = new XElement("Name", node.Text);
n.Add(name);
foreach (TreeNode tn in node.Nodes)
{
XElement n2 = new XElement("子ノード");
n.Add(n2);
XmlRecursive(tn, n2);
}
}
結果はこんな感じ。

ノードのラベル名は<Name>タグに格納しています。
同じように、ノードに紐づけたクラスインスタンスの情報‥例えばノードと紐づけたTextBoxの内容など色々な情報をタグにして埋め込むことができます。
これが不要で単純にノードのラベル名がそのままタグ名になるだけで良いなら、こんなまわりくどくする必要は無くて、もっと簡略化できると思います。
ちなみに文字列をXMLに書き出す際、改行が失われてしまいます。
なので改行を表す特殊文字に置き換えて読み書きすることで対応しました。
「memo.Text.Replace("\r\n", "[:NL:]");」みたいな感じです。
タブスペースは何もしなくても保持されました。
置換の方法はこちらをどうぞ。
XMLの書き出しは初めて試した状態なので、もっと良い方法があればぜひコメントくださいっ。