XSLTスタイルシート書き方講座 :応用編(2)
XMLデータの埋め込みと相互参照
株式会社日本ユニテック
奥井康弘、吉田稔、青木秀起
2002/2/20
| 複数のXMLデータを組み合わせて処理する |
XSLTプロセッサの基本的な処理の流れは、与えられた単一のXMLデータにスタイルシートを適用して構造変換を行うというものです。しかしマージ処理のように、複数のXMLデータを処理したいときがあるものです。例えば下図のように、メインのXMLデータにディテール・ファイル(詳細情報を持つファイル)の内容をさらに組み込めたら便利です。
![]() |
| 図1 複数のXMLデータを組み込む |
大容量のXMLデータを作成するのではなく、図1のように細かくいくつかのファイルに切り分け、これらを組み合わせて使え、データの管理も処理も容易になります。実は、これを可能にしてくれるのがXSLTのdocument関数です。document関数は、最初に与えられるメインのXMLデータ以外のXMLデータを読み込んでくれます。
■document関数を使ってXMLデータを読み込む
document関数は次のように呼び出します。
document関数の使い方node-set document(object, node-set?)
|
document関数の2番目の引数について説明を補足します。もし1番目の引数が“customers.xml”のように相対URIの場合、document関数は読み込み対象のXMLデータを見つけ出すために基底URIを使って絶対URIへと変換する必要があります。そのために2番目の引数が使われます。次の例を見てください。
document("customers.xml","/") |
メインのXMLデータのルートノード(/)が“ http://seminars.utj.co.jp/main.xml”という基底URIを持っているならば、customers.xmlは“http://seminars.utj.co.jp/customers.xml”という絶対URIに変換されます(図2)。
![]() |
| 図2 基底URIで相対URIを絶対URIへ変換する |
例を使ってdocument関数の使用方法を示しましょう。リスト1に示すメインのXMLデータ“main.xml”と、リスト2に示す読み込み対象のXMLデータ“customers200110.xml”を使って新規顧客表を作成して、Webブラウザに表示するとします。
<?xml version="1.0" encoding="shift_jis"?> |
| リスト1 メインのXMLデータ“main.xml” |
<?xml version="1.0" encoding="shift_jis"?> |
| リスト2 読み込み対象のXMLデータ“customers200110.xml” |
適用するスタイルシート“tboutput.xsl”をリスト3に示します。
<?xml version="1.0" encoding="Shift_jis"?> |
| リスト3 document関数を使うスタイルシート |
このスタイルシートについて解説します。リスト1とリスト3を比較して分かるとおり、XSLTプロセッサは、まずメインのXMLデータを処理します。メインのXMLデータにtbl要素が出現すると、XSLTプロセッサは、新規顧客表を作成します。そこで“customers200110.xml”が読み込まれます。
リスト1のtbl要素をご覧ください。tbl要素の属性hrefには、読み込み対象のXMLデータのURIが割り当てられています。
<tbl href="customers200110.xml"/> |
リスト3のdocument関数を呼び出しているところを見てください。ここでdocument関数は、@hrefという表記で分かるとおり、カレントノードtbl要素の属性hrefの値を参照してXMLデータ“customers200110.xml”にアクセスします。返却値は、“customers200110.xml”のルートノードです。
document(@href) |
このルートノードは、すべてのcustomer要素を参照するために繰り返し使用されます。それで、xsl:variable要素を使ってルートノードを変数tに割り当てておきます。
<xsl:variable name="t"
select="document(@href)"/> |
“customers200110.xml”のルートノード以下のすべてのcustomer要素について、テンプレートがインスタンス化されます。変数の値を参照するときは、変数名の頭に“$”の文字を付けて“$t”と記述します。従って“$t//customer”という表記は、変数$tに割り当てられているルートノードの子孫ノードcustomerを指しています。
<xsl:for-each select="$t//customer"> |
IE5による表示結果を図3に示します。
![]() |
| 図3 document関数を使うサンプルの表示結果 |
| 相互参照するノードを識別する |
複数のXMLデータの扱いなど、処理が複雑になってくるとXSLTのあるノードから別のノードへ効率的に相互参照する仕組みが欲しくなります。XSLTでは、ビルトイン関数idやビルトイン関数keyを使ってノードの相互参照を実現することができます。
■id関数を使って相互参照する
まず、id関数について説明します。
id関数の使い方
|
id関数の使い方をリスト4のXMLデータを使って示します。
<?xml version="1.0" encoding="shift_jis"?> |
| リスト4 id関数のためのサンプルXMLデータ |
適用するスタイルシートはリスト5にあるとおりです。
<?xml version="1.0" encoding="shift_jis"?> |
| リスト5:id関数を使ったスタイルシート例 |
この中でid関数が使われている部分を見てください。
<li><xsl:value-of select="id('c004')/name"/>様</li> |
id('c004')という記述は、属性id(DTDで属性のデータ型がID型に宣言されている)の値が“c004”となるcustomer要素のことを表しています。ここでは、その要素の子要素nameの文字列値をHTMLタグ<li></li>の間に要素の内容として埋め込んでいます。
IE 5による表示結果を図4に示します。
![]() |
| 図4 id関数を使うサンプルの表示結果 |
■id関数の限界
しかしながら、id関数には以下の限界があります。
- ID属性がDTDなどで定義されていなければならない。
- IDは属性として指定する。従って要素の内容を使った参照ができない。
- 1つの要素が持てるIDは1つだけ。
そこで、ID型として定義されていなくても、スタイルシートの中で定義すれば相互参照ができるようにしたのがkey関数です。
■key関数を使って相互参照する
id関数は、DTD(あるいはXML Schemaなどのスキーマ記述言語)でID型として明示的に宣言された属性をノードの識別情報として使う関数です。一方、これから説明するkey関数は、ある要素の文字データや属性の値(ID型でなくてよい)をキーとしてスタイルシートの中で定義し、それをノードの識別情報に使うための関数です。
key関数で使用するキーは、スタイルシートの中でxsl:key要素を使ってあらかじめ宣言する必要があります。xsl:key要素の書き方は以下のとおりです。
xsl:keyの書き方<xsl:key name="キーの名前" match="パターン" use="式"/>
|
xsl:key要素で宣言されたキーを実際に参照するkey関数の書き方は以下のとおりです。
key関数の使い方node-set key(string, object)
|
リスト2のXMLデータを使って、key関数の使い方を示します。リスト6のスタイルシート“key.xsl”を適用します。
<?xml version="1.0" encoding="shift_jis"?> |
| リスト6 key関数を使ったスタイルシートの例 |
key要素が使われているところを以下に抜き出します。
<xsl:key name="area-key"
match="customer" use="area"/> |
name属性により、キーの名前として“area-key”を指定しています。match属性により、キーを割り当てるノードとしてcustomer要素を指定しています。さらにuse属性により、customer要素をコンテキストノードとしたときのarea要素の文字列値がキーとして使用されることを指定しています。
key関数が使われている部分を以下に抜き出します。
<xsl:for-each 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に示します。
![]() |
| 図5 key関数を使うサンプルの表示結果 |
■まとめ
今回は、document、id、keyという3つの関数を取り上げ、複数のXMLデータを操作する方法と、相互参照機能を使って必要なデータを抽出する方法について説明しました。次回は、結果ツリーのファイル出力、およびXSLT要素や関数の拡張について解説します。
| 本記事は、日本ユニテック発行のXMLテクノロジー総合情報誌「Digital Xpress」に掲載された、XSLT特集「XSLTの実力を探る!」の内容をもとに、加筆修正したものです。 |
| ファイル出力とXSLT機能拡張 |
| XSLTスタイルシート書き方講座 | |
| XSLTスタイルシートの基礎の基礎 | |
| XPathの書き方の基本 | |
| XSLTの初歩的プログラミング | |
| XSLTによるデータのソートと変数とパラメータ | |
| スタイルシートをモジュール化する | |
| XMLデータの埋め込みと相互参照 | |
| ファイル出力とXSLT機能拡張 | |
- QAフレームワーク:仕様ガイドラインが勧告に昇格 (2005/10/21)
データベースの急速なXML対応に後押しされてか、9月に入って「XQuery」や「XPath」に関係したドラフトが一気に11本も更新された - XML勧告を記述するXMLspecとは何か (2005/10/12)
「XML 1.0勧告」はXMLspec DTDで記述され、XSLTによって生成されている。これはXMLが本当に役立っている具体的な証である - 文字符号化方式にまつわるジレンマ (2005/9/13)
文字符号化方式(UTF-8、シフトJISなど)を自動検出するには、ニワトリと卵の関係にあるジレンマを解消する仕組みが必要となる - XMLキー管理仕様(XKMS 2.0)が勧告に昇格 (2005/8/16)
セキュリティ関連のXML仕様に進展あり。また、日本発の新しいXMLソフトウェアアーキテクチャ「xfy technology」の詳細も紹介する
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
- - PR -
- - PR -
お勧め求人情報













