自分で書いて,しくみを理解!

古いけれども今も使える『無料の』技術で,Webプログラミングの面白さを,再発見してみましょう! ぜひ,リストを追いながら,初心にかえって,入力してみてください。プログラミングの楽しさを実感できることでしょう。

 今回は,ユーザーが入力したデータから,XMLツリーを生成してみましょう。まずは1行のデータをからなるXMLツリーを生成する処理で基本を把握し,属性付きのXMLツリーの生成,データ件数分要素が繰り返すXMLツリーの生成というように,段階を追って見ていきます。今回もJScriptを扱っていますので,表示ブラウザはInternet Explorer限定となります。

データが1件のXMLツリーを生成する

 まずは,入力したデータをもとに,リスト1のようなデータが1件のXMLツリーを生成し,表示させてみましょう。実行画面は図1のようになります。ルート要素は<全体>で,その中に<情報>要素があり,さらに子要素として<メッセージ>要素があり,<メッセージ>要素の内容として,ユーザーの入力したデータが入るというものです。

リスト1●生成するXML文書(クリックで別ウィンドウで表示します)

図1●入力したデータを元に,1件のデータのXMLツリーを生成したところ(クリックで別ウィンドウで表示します)

リスト2図1のソースコード/Internet Explorer限定(ソースをこちらからダウンロードできます,クリックで別ウィンドウで表示します)

 XMLツリーの生成は,「各ノードを作っては追加していく」という作業になります。まず,XHTML内に<input>要素をレイアウトして,ユーザーの入力ボックスを生成します(リスト2の下から6行目)。name属性にはuserDataを指定しておきます。

<input type="text" size="30" name="userData" />
 次に,<button>要素をレイアウトし,ボタンの文字を「XMLの生成」とし,onClickイベントにmakeXmlイベントハンドラを指定します。

<button onClick="makeXml()">XMLの生成</button>
 そして,「XMLの生成」ボタンをクリックして生成されるXMLを表示させるために,<textarea>要素をレイアウトします。name属性はxmlDataSourceとし,readonlyにtrueを指定して,読み込み専用とし,編集はできないようにしておきます。

<textarea name="xmlDataSource" cols="50" rows="7" readonly="true"></textarea>
 ボタンをクリックすると実行されるmakeXmlの処理を見ていきましょう。

 リスト2の(1)では,まず,入力ボックス(nameがuserDataの<input>要素)に入力されたデータを,変数xmlDataに格納しておきます。

 2行目では,ActiveXObjectオブジェクトでMSXMLDOMオブジェクトを作成します。DOMのasyncプロパティにfalseを指定してXMLファイルの読み込みを同期読み込みにします。loadXMLメソッドで,XML宣言とルート要素<全体>だけのXMLツリーをロードします。

 ここで,いずれもXMLを読み込むメソッドであるloadXMLメソッドとloadメソッドの違いについて説明しておきましょう。

 loadXMLメソッドの構文は次のようになります。

戻り値=XML文書を表すオブジェクト.loadXML(文字列)
 loadXMLでは,文字列からXML文書を読み込みます。つまり,「文字列」の部分に,XML文書オブジェクトの中に読み込むXML文書の文字列を指定します。読み込みが成功した場合はtrueが,失敗した場合はfalseが戻り値として返されます。

 loadメソッドの構文は次のとおりです。

戻り値=XML文書を表すオブジェクト.load(読み込むXMLファイルのURI)
 URIを指定して,XMLファイルを呼び出します。呼び出しに成功した場合はtrueが,失敗した場合はfalseが戻り値として返されます。

 リスト2の(2)では,createTextNodeメソッドで改行(\n)テキストノードを生成し,appendChildメソッドで,ルート要素に追加します。

 JScriptでXMLを生成する場合,自動的に改行をさせる関数はありません。改行させなければ,すべてが1行で表示されてしまうため,createTextNodeメソッドで改行を生成しては,必要な要素に追加していく必要があります。

 (3)では,createElementメソッドで<情報>要素を生成します。createTextNodeメソッドで改行テキストノードを生成し,appendChildメソッドで,<情報>要素に追加します。

 (4)ではcreateElement要素で<メッセージ>要素を生成しています。生成した<メッセージ>要素の内容を,createTextNodeメソッドで生成します。ここで生成する<メッセージ>要素の内容は,(1)で格納しておいた,入力ボックスに入力されたデータである,xmlData変数の内容です。appendChildメソッドで,生成した<メッセージ>要素に,生成した内容を追加します。

 (5)ではappendChildメソッドで,(3)で生成した<情報>要素に,(4)で生成した<メッセージ>要素を追加します。同時に改行テキストノードも生成して<情報>要素に追加します。

 (6)ではappendChildメソッドで,<メッセージ>要素を子要素として持つ<情報>要素をルート要素に追加します。同時に改行テキストノードも生成してルート要素に追加します。

 最後に(7)で,xmlDataSourceというnameを持つ<textarea>要素内に,生成したXML文書を表示します。

 要素や改行を生成して追加する処理手順は,慣れなければわかりにくいものです。最初のうちは次のように,3段階に分けて考えると,わかりやすくなります。

(1)まず,各要素が何を含むか考えます。
(2)含むものを生成します。
(3)生成したものを追加します。

 リスト1のXMLは,<全体><情報><メッセージ>要素から成ります。これらの各要素について,(1)(2)(3)の方法で,処理手順を考えると,次のようになります。

<全体>要素
(1)<全体>要素は,改行を表すテキストノードと,子要素の<情報>要素と,改行を表すテキストノードを含みます。
(2)それらを生成します。
(3)<全体>要素に,生成した改行と,<情報>要素と,改行を追加するコードを,これらが同じ階層なので,並列になるように書きます。

<情報>要素
(1)<情報>要素は,改行を表すテキストノードと,子要素の<メッセージ>要素と,改行を表すテキストノードを含みます。
(2)それらを生成します。
(3)<情報>要素に,生成した改行と,<メッセージ>要素と,改行を追加するコードを,並列になるように書きます。

<メッセージ>要素
(1)<メッセージ>要素は,入力したデータをもとにしたテキストノードを含みます。
(2)入力したデータをもとにしたテキストノードを生成します。
(3)<メッセージ>要素に,テキストノードを追加します。

 これらの3段階の手順を追いながら,確実にコードを書いていけば,図2のように,入れ子になったツリーを生成できるわけです。

図2●<全体><情報><メッセージ>という三つの要素を生成する考え方。わかりやすいように,インデントして三つの要素を色でブロック分けしている

 生成したテキストノードや子要素を追加していく手順がわかりにくい場合は,プログラムで変数に値を代入するときと同じ考え方をするとよいでしょう(図3,上図)。代入するように追加していくことで要素は入れ子になっていきます(図3,下図)。

図3●テキストノードや子要素を生成して代入していく考え方

 以上が,要素のみのXMLツリーの生成方法です。