});前回の「スタイルシートをモジュール化する」では、モジュール化された複数のスタイルシートを取り込む方法を考えました。スタイルシートだけでなく、XMLデータも複数のファイルを扱えると便利です。データベースから複数のXMLデータを読み込んで結合したり、必要なデータのみを選んで抽出することができれば、XMLデータの操作性はさらに向上することでしょう。今回は、複数のXMLデータを操作する方法と、相互参照機能を使って必要なデータのみを抽出する方法を説明します。複数のXMLデータを組み合わせて処理するXSLTプロセッサの基本的な処理の流れは、与えられた単一のXMLデータにスタイルシートを適用して構造変換を行うというものです。マージ処理のように、複数のXMLデータを処理したいときがあるものです。下図のように、メインのXMLデータにディテール・ファイル(詳細情報を持つファイル)の内容をさらに組み込めたら便利です。複数のXMLデータを組み込む大容量のXMLデータを作成するのではなく、図1のように細かくいくつかのファイルに切り分け、これらを組み合わせて使え、データの管理も処理も容易になります。実は、これを可能にしてくれるのがXSLTのdocument関数です。document関数は、最初に与えられるメインのXMLデータ以外のXMLデータを読み込んでくれます。■document関数を使ってXMLデータを読み込むdocument関数は次のように呼び出します。(URI指定)(基底URI)基本的に1番目の引数で読み込み対象のXMLデータのURIを指定します。2番目の引数がある場合、それは相対URIである1番目を絶対URIに変換するための基底URIです。返却値は、読み込み対象のXMLデータのルートノードです。document関数の2番目の引数について説明を補足します。1番目の引数が“customers.xml”のように相対URIの場合、document関数は読み込み対象のXMLデータを見つけ出すために基底URIを使って絶対URIへと変換する必要があります。そのために2番目の引数が使われます。次の例を見てください。http://seminars.utj.co.jp/main.xml”という基底URIを持っているならば、customers.xmlは“http://seminars.utj.co.jp/customers.xml”という絶対URIに変換されます(図2)。基底URIで相対URIを絶対URIへ変換する例を使ってdocument関数の使用方法を示しましょう。リスト1に示すメインのXMLデータ“main.xml”と、リスト2に示す読み込み対象のXMLデータ“customers200110.xml”を使って新規顧客表を作成して、Webブラウザに表示するとします。読み込み対象のXMLデータ“customers200110.xml”適用するスタイルシート“tboutput.xsl”をリスト3に示します。document関数を使うスタイルシートこのスタイルシートについて解説します。リスト1とリスト3を比較して分かるとおり、XSLTプロセッサは、まずメインのXMLデータを処理します。メインのXMLデータにtbl要素が出現すると、XSLTプロセッサは、新規顧客表を作成します。そこで“customers200110.xml”が読み込まれます。リスト1のtbl要素をご覧ください。tbl要素の属性hrefには、読み込み対象のXMLデータのURIが割り当てられています。href="customers200110.xml"/>リスト3のdocument関数を呼び出しているところを見てください。ここでdocument関数は、@hrefという表記で分かるとおり、カレントノードtbl要素の属性hrefの値を参照してXMLデータ“customers200110.xml”にアクセスします。返却値は、“customers200110.xml”のルートノードです。document(@href)このルートノードは、すべてのcustomer要素を参照するために繰り返し使用されます。それで、xsl:variable要素を使ってルートノードを変数tに割り当てておきます。select="document(@href)"/>“customers200110.xml”のルートノード以下のすべてのcustomer要素について、テンプレートがインスタンス化されます。変数の値を参照するときは、変数名の頭に“$”の文字を付けて“$t”と記述します。従って“$t//customer”という表記は、変数$tに割り当てられているルートノードの子孫ノードcustomerを指しています。</tr></xsl:for-each>IE5による表示結果を図3に示します。相互参照するノードを識別する複数のXMLデータの扱いなど、処理が複雑になってくるとXSLTのあるノードから別のノードへ効率的に相互参照する仕組みが欲しくなります。XSLTでは、ビルトイン関数idやビルトイン関数keyを使ってノードの相互参照を実現することができます。■id関数を使って相互参照するまず、id関数について説明します。id(object)(返却値)(ID型の属性値)引数で指定された値と同じ一意のID値を持つノード、またはノード集合を返却します。id関数の使い方をリスト4のXMLデータを使って示します。id関数のためのサンプルXMLデータ適用するスタイルシートはリスト5にあるとおりです。<h3>お客様IDがc004の方は次の方です。</html></xsl:template></xsl:stylesheet>リスト5:id関数を使ったスタイルシート例この中でid関数が使われている部分を見てください。select="id('c004')/name"/>様</li>id('c004')という記述は、属性id(DTDで属性のデータ型がID型に宣言されている)の値が“c004”となるcustomer要素のことを表しています。ここでは、その要素の子要素nameの文字列値をHTMLタグ<li></li>の間に要素の内容として埋め込んでいます。5による表示結果を図4に示します。■id関数の限界しかしながら、id関数には以下の限界があります。ID属性がDTDなどで定義されていなければならない。IDは属性として指定する。従って要素の内容を使った参照ができない。1つの要素が持てるIDは1つだけ。そこで、ID型として定義されていなくても、スタイルシートの中で定義すれば相互参照ができるようにしたのがkey関数です。Schemaなどのスキーマ記述言語)でID型として明示的に宣言された属性をノードの識別情報として使う関数です。これから説明するkey関数は、ある要素の文字データや属性の値(ID型でなくてよい)をキーとしてスタイルシートの中で定義し、それをノードの識別情報に使うための関数です。key関数で使用するキーは、スタイルシートの中でxsl:key要素を使ってあらかじめ宣言する必要があります。xsl:key要素の書き方は以下のとおりです。use="式"/>name属性は、キーの名前を指定します。match属性は、キーを割り当てるノードを指定します。use属性は、指定された式の評価結果をキーの値とします。use属性の式を評価するに当たってのコンテキストノードはmatch属性のノードになります。xsl:key要素で宣言されたキーを実際に参照するkey関数の書き方は以下のとおりです。object)(返却値)(キーの名前)(キーの値)返却値は、第1引数のキーの名前と第2引数のキーの値を持つノード集合です。リスト2のXMLデータを使って、key関数の使い方を示します。リスト6のスタイルシート“key.xsl”を適用します。<h3>関東地方にお住まいのお客様は次の方々です。key関数を使ったスタイルシートの例key要素が使われているところを以下に抜き出します。use="area"/>name属性により、キーの名前として“area-key”を指定しています。match属性により、キーを割り当てるノードとしてcustomer要素を指定しています。use属性により、customer要素をコンテキストノードとしたときのarea要素の文字列値がキーとして使用されることを指定しています。key関数が使われている部分を以下に抜き出します。select="key('area-key','関東')">key関数の最初の引数は、key要素において“area-key”という名前で宣言されたキーを使用することを指定しています。2番目の引数はキーの値を指定しています。この場合、key関数はcustomer要素の子要素areaの文字列値が“関東”となる要素を返却します。ID型の属性値は、1つのXMLデータの中で一意でなければなりません。従って同じID値を持つ要素が存在してはなりません。同じキー値を持つ要素は複数あっても構いませんし、1つの要素が複数の種類のキーを持ってもかまいません。したがって、key関数によって複数のノードを参照することもあり得ます。リスト2のXMLデータの場合、キーの値であるareaの文字列値が“関東”となる要素が複数存在しています(id属性が“c001”のcustomer要素と“c002”のcustomer要素)。リスト6では繰り返し処理を行うfor-each要素を使ってkey関数が参照するすべての要素を処理しています。処理結果を図5に示します。■まとめ今回は、document、id、keyという3つの関数を取り上げ、複数のXMLデータを操作する方法と、相互参照機能を使って必要なデータを抽出する方法について説明しました。次回は、結果ツリーのファイル出力、およびXSLT要素や関数の拡張について解説します。Xpress」に掲載された、XSLT特集「XSLTの実力を探る!」の内容をもとに、加筆修正したものです。メールマガジンをご購読ください。申し込みページへITmediaはアイティメディア株式会社の登録商標です。