今度は、XML文書を用いて階層的なデータ構造を表現しているような例を取り上げます。階層的なデータ構造といってもピンとこないかもしれませんが、それほど難しく考える必要はありません。皆さんがお使いのWindowシステム(例えばWindows)でおなじみのポップアップメニューのメニュー項目などがよい例でしょう。このポップアップメニューのメニュー項目を、XMLで表現することを考えてみます。図1に示すのは、Windowsのコンテキストメニューの一例です。単純に考えれば、リスト3のような形で表示されているメニュー項目を列挙するだけでよさそうです。メニュー項目を単純に列挙してみるメニューを表現しているのがmenuタグで、メニュー項目を表現しているのがitemタグです。いうまでもなくlabel>タグの文字列は、メニュー項目のラベルにあたります。「アイコンの整列(I)」などは実際にはサブメニューになっています(図2)。サブメニューの例こう考えると、リスト3のような形では少し不十分で、リスト4に示すようにmenu自体も項目として定義する必要があるでしょう。サブメニューも項目として取り扱うこのように表現されているメニュー情報を読み込んで、最終的に図3に示すようなクラスのインスタンスで表現することに挑戦してみます。メニュー情報を格納するためのクラスMenuItemがメニュー項目の情報を表し、Menuはそのリストを格納します。Menu自身がMenuItemの派生クラスになっているところがポイントです(この手の構造を表現するパターンとしては常とう手段ですね)。それぞれのクラスの詳細についてはここで説明しませんが、メソッドの名前からだいたい想像できるでしょう(詳細が知りたい方は、リスト5のソースを参照してください)。以下で基本的なアプローチについて述べた後、実際のソース(リスト5)について見ていきますが、その前に読者の皆さんは各自で、どのように実現するのか一度考えてみてください。基本的なアプローチは、以下のとおりです。工夫が必要なのは、「親メニューに追加」のところです。menuタグは入れ子にすることができます。menuの開始タグが新たに現れるたび、親メニューは変わることになりますが、終了タグが現れた時点で、変更前のものに戻さなくてはなりません。お分かりの方もいるかと思いますが、こういう場合、スタックを用いて管理するのが適当です。具体的な使い方についてはソースを直接見た方が早いでしょう(リスト5)。メニュー情報を読むためのハンドラ(MenuHandler.java)ソースを見ると分かるように、32行目のstartElementでタグの情報を格納するためのオブジェクトを生成し、52行目のendElementでそのオブジェクトを親メニューに格納するという処理をしています。ポイントは親メニューを格納するためのスタックparentsです。ここでは8行目にあるように、Vectorを用いてスタックを実現しています。startElementでmenuタグを認識した場合に、親メニューをスタックに格納していることを確認してください。このような入れ子の構造を処理する場合にスタックを用いるのは、SAXプログラミングにおける常とう手段の1つといえるでしょう。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。