[IM]ノードの展開

もとになるHTMLによるDOMがあって、そこからデータベースのデータに置き換わったノードが展開される様子を一般的に記述できるように、改めて解析を行います。概ね、左の図がもとのDOMで、エンクロージャーを起点にしてリピーターが展開されれたものが右側です。リピータの繰り返し処理を行う場合、リピーターはいったんエンクロージャーの子ノードではなくし、そのクローンを作ってデータベースからのデータを設定し、エンクロージャーの子ノードとして追加するという作業を行います。つまり、R10はノードのひな形であり、実際にデータベースの内容を展開するのは、そのクローンであるR11、R12…です。R10に含まれるリンクされた要素のL101は、データベースの値を設定された場合にはL111、L121となっています。いずれにしても、この番号付けのルールはうまく重複は存在しません。ただし、単に十進数にすると、桁が増えたときの問題になりますので、ユニークな識別子は各桁をハイフンで結ぶなどする必要があります。最終的には、各ノードのidフィールドを与える必要があるので、「R-1-2-1-1」のような各桁をハイフンで区切った文字列を識別子とします。このような識別子にしておけば、リンクされた要素からエンクロージャーやリピータを見つけるのがやりやすくなります。なお、リピーターが複数の要素からなる場合は、「R-1-2-1-1-1」のように一桁多くしておきます。リピーターは「R」以下、偶数桁なので、奇数桁となっている場合には末尾が複数の要素の何番目かを示すものであることが分かります。また、数値の0はひな形、1以降が展開された要素を示すというルールにします。

76896

 

この図から、一連の処理を以下のように組み立てることができることが分かります。これにより、リカーシブにノードをたどることで、すべてのエンクロージャー/リピータをデータベースの内容に置き換えて複製展開できます。つまり、seekNodesとexpandEnclosureを順次呼び出すことで、展開ができるということになります。

  1. seekNodesにより、最上位のノードから見たときに最初に到達されるエンクロージャーが見つかる
  2. そのエンクロージャーに対してexpandEnclosure関数を実行する
  3. expandEnclosureでは、リピータをエンクロージャーから取り除き、そのクローンを作って複製する用意をする
  4. 続いて、リンクされる要素を探し出してリストアップする
  5. リストの情報からデータベースヘ接続し、関連付ける必要のあるデータを得る
  6. レコードの数だけリピータの複製、データの埋め込み、エンクロージャーへの追加を行う
  7. リピーターを起点として、seekNodesによりエンクロージャーを見つける
  8. エンクロージャーに対してexpandEnclosure関数を実行する
  9. …以下繰り返し

 

ここで考える必要があるのは、主キー/外部キーのデータを伝達する必要があるということです。expandEnclosure関数ではデータベースにアクセスしてデータを取り出しますが、そのとき、現在のエンクロージャーの上位のエンクロージャーで展開しているリピーターとの連動が必要です。すなわち、上位から、テーブル名、主キーフィールド名、その値をもらわないといけません。つまり、expandEnclosure関数で、これらを引数として引き渡す必要があります。そして、現在のエンクロージャーのリピーターを展開するためのデータを得る時、リピーターに対応するテーブルにおいて、上位のリピータととのリレーションが設定されているかどうかを確認し、設定されているようなら、上位のエンクロージャーからの情報を検索条件に含める必要があります。

なお、このあたりで、ずっと関数で書いていたプログラムを、オブジェクトにカプセル化することにします。当面、外から呼び出すのに必要なメソッドはないので、単にこれまでに書いて来た関数を、以下のようにコンストラクタの中に閉じ込めてしまうことにします。

function INTERMediator( rootNode ) {
 
seekNodes( rootNode );
      :
}
}