図書館情報学を学ぶ

はてなダイアリーで公開していたブログ「図書館情報学を学ぶ」のはてなブログ移行版です。

XMLプログラミング

4月から今日まで、「情報表現法」という講義でXMLについて学んでいました。講義ではXMLの書き方、DTDによるスキーマ定義、XPathによる要素指定などを簡単に解説されていて、途中に演習が挿入されていたのですが、XMLについて以前少しかじったことがあるので少し物足りないというのが正直な感想でした。
そこで、以下のページを参考にして、C#によるXMLプログラミングを授業内容と平行して学習してみました。

Visual C# による XML チュートリアル 第 3 回:Visual C# による簡易 XML エディタ
http://www.microsoft.com/japan/msdn/academic/Articles/xml/03/xml3.asp

上のページに書かれているサンプルは、XMLファイルを読み込んで、ツリー表示し、選択した要素の内容をテキストボックスに表示するというものです。あまり複雑な構造ではないので、すぐにクリアできると思っていたのですが、実際にやってみると、正確に要素内容を表示できない。例えば、以下のようなXMLファイルがあったとします。




お茶
150


オレンジジュース
110


イカジュース
200




おにぎりセット
500


パスタセット
680




アイスクリーム
180


おしるこ
200



このXMLファイルを読み込むと、以下のようなツリーとして表示されます。

一見正常に読み込んでいるようですが、要素を選択してみると、どの要素を選択しても、最初の要素の内容しか表示されません。
この障害が何故起こるのかしばらく頭を抱えてしまいました。WindowsプログラミングもC#XMLプログラミングも初めてという無謀な状態でプログラミングをしていたので、まあ壁にぶち当たるのは当然かもしれません。
結局、この障害は、ツリー要素を選択したときに得られるパスが、XMLPathと対応していないというのが原因でした。つまり、「/menu/item[1]/name」のようなXPath式が必要なのに、ツリーオブジェクトが渡すパスは「\menu\item\name」と全く対応してなかったのが原因。\から/への変換はページ中のコードに載っていたのですが、インデックスを付与するための関数はどこにも定義されていませんでした。何故だろう???C#1.0ではこれで正常に動作していたとか?
まあ、結局以下のようなコードを書いてパスを変換し、正常に表示するようにデバグしました。

private string getpath(TreeNode tree)
{
if (tree.Parent != null)
{
return getpath(tree.Parent) + "/" + tree.Text + "[" + getindex(tree) + "]";
}
else
{
return "/"+tree.Text;
}
}
このような再帰的にツリーを走査していく方式をTreeWalkerと言うらしいです。(by 情報表現法のN先生)これでそれぞれの要素名にインデックスを付与したXMLPath式に変換することができます。
しかしこれでも、item要素の子要素priceの内容を表示することができません。原因はツリーオブジェクトが付与するインデックスは要素別ではなく、同じ階層にある要素全体のインデックスなので、priceにname[1]に続いて[2]というインデックス番号を付与していること。まだこの部分は解決できていないので、また追々コードを書いてみようと思います。ちょっとC#オブジェクト指向の解説を入れた方が良いのかもしれないですね。まあいずれ詳細を書こうと思います。