XSLTがW3C勧告となってから早2年がたち、XSLT機能を内蔵したツールも充実してきました。XSLTの利用目的として、XML文書をHTML化して“見せる”ためだけでなく、データの“変換”機能がビジネスで活用されるようになっています。「XSLTスタイルシート書き方講座」の新シリーズ「応用編」では、ビジネスへの応用を意識した、複雑で柔軟なデータ変換機能について考えてみましょう。
応用編の第1回は、「XSLTスタイルシートのモジュール化」です。大規模で複雑なスタイルシートをいくつかのモジュールに分割すれば、開発や保守が簡単になります。また共通して使う機能をモジュールとして切り分ければ、部品として流用できるので開発効率を上げることができます。今回は、複数のXSLTスタイルシートを組み合わせるための機能を説明します。
まず下のイメージ図をご覧ください。
複雑で大きなスタイルシートを1ファイルにまとめて作成すると、開発するのも変更などの保守を行うのも大変です。しかし、図1のように、スタイルシートをいくつかのモジュールに分割すれば、開発や保守もかなり楽になります。図1では、A氏とB氏に分割してスタイルシートの開発を依頼し、それらをメインのスタイルシートに取込んでいます。こうすれば開発や改変などの保守を複数の人が分担して行うことができます。また、このように開発されたモジュール化スタイルシートをほかの部課で利用することも可能になります。
例えば、製品開発第1課で開発した製品データベースのスタイルシートを、第3営業部で流用することもできるようになります。さらに、XSLTの機能をフル活用すれば、改変を効率的に行うことができます。というのも、改変したい部分だけを元のスタイルシートに上書きするかのように読込めるのです。
これらを実現するのが、今回ご紹介する以下の2つの要素です。
この2つの要素を使ってどのようにスタイルシートを取込むのでしょうか。両者の機能上の違いはどこにあるのでしょうか。使い分けることにより何が可能になるのでしょうか。順に解説いたします。
スタイルシートの中でxsl:include要素またはxsl:import要素を書くと、参照先スタイルシートを取込むことができます。xsl:includeを例に取ると、書き方は以下のとおりです。
─xsl:includeの書き方─
<xsl:include href=インクルードされるスタイルシートのURI参照/>
(注)href属性は必須
参照先スタイルシートは、スタイルシートとして完全な形をしていなければなりません。つまり、xsl:stylesheet要素を持っていなければなりません。従って参照先スタイルシートを取込むとは、正確にいうと参照先スタイルシートのxsl:stylesheet要素の子要素以下がxsl:include要素に置き換えられるということです。
スタイルシートがどのように取込まれるかイメージをつかんでいただくため、リスト1に示す書評のXMLデータ“reviews.xml”を使った例を示しましょう。このXMLデータをWeb表示させるためのXSLTスタイルシート“web-sheet.xsl”をリスト2に示します。
<?xml version="1.0" encoding="shift_jis"?> |
リスト1 書評のXMLデータ“reviews.xml” |
<?xml version="1.0" encoding="Shift_jis"?> |
リスト2 適用されるXSLTスタイルシート“web-sheet.xsl” |
リスト2で、ほかのXSLTスタイルシートをインクルードしているところを以下に抜き出しました。
<xsl:include href="booklist.xsl"/> |
上記の例では、書評一覧の本体は別のスタイルシート“booklist.xsl”を参照しています。こうしておくことで、書評一覧を表や個条書きのような別の形式に変えたい場合に、参照元のスタイルシートを変更することなく、参照先スタイルシートを変えるだけで済むので簡単です。その参照先スタイルシート“booklist.xsl”を、リスト3に示します。
<?xml version="1.0" encoding="Shift_jis"?> |
リスト3 個条書きで表示する場合の参照先スタイルシート“booklist.xsl” |
リスト1に示したXMLデータにリスト2のスタイルシートを適用した結果をInternet Explorerで表示した画面を示します。前回までの記事と同様、MSXML3.0がインストールされている環境での実行結果です。
xsl:include要素もxsl:import要素も、xsl:stylesheet要素の子要素でなければなりません。例えば、リスト4に示したような位置にxsl:include要素を書くことができます。
注:xsl:stylesheet要素の子要素のことを「トップレベル要素」といいます。
<?xml version="1.0" encoding="shift_jis"?> |
リスト4 xsl:includeの正しい位置 |
一方、リスト5の位置はエラーになります。ルート要素であるxsl:stylesheet要素の子要素xsl:template要素の、さらに子要素としてxsl:include要素が記述されていて、トップレベル要素になっていないからです。
<?xml version="1.0" encoding="shift_jis"?> |
リスト5 xsl:includeの誤った位置 |
なお、自分自身をインクルードすることはエラーになります。また同じスタイルシートを2度以上インクルードすることもエラーになります。参照先のスタイルシートがさらに別のスタイルシートを参照していく深い階層構造の場合、インクルードの重複に注意する必要があります。
先ほどはxsl:includeの例を見ましたが、こんどはxsl:importについて解説していきます。xsl:importは、以下の2つの点でxsl:includeとは異なっています。
(1)取込むスタイルシートに優先順位が付けられる
xsl:includeは単なる置き換えなので、 複数のスタイルシートが競合してしまうことがあり得ます。しかし、xsl:importの場合、参照元スタイルシートと参照先スタイルシートの間に重複がある場合、参照元スタイルシートの定義やテンプレートルールが優先されます。3つ以上のスタイルシートがインポートされる場合の優先順位については、W3CによるXSLT 1.0の勧告を参照してください。
(2)位置に関する制約がある
xsl:import要素は、xsl:stylesheet要素の子要素の先頭に位置しなければなりません。一方、xsl:include要素は、トップレベル要素であれば任意の場所に置くことができます。リスト6のスタイルシートでは、xsl:import要素が正しい位置にきています。
<?xml version="1.0" encoding="shift_jis"?> |
リスト6 xsl:importの正しい位置 |
一方、リスト7の位置はエラーになります。xsl:import要素に先行するxsl:include要素が1つあるからです。
<?xml version="1.0" encoding="shift_jis"?> |
リスト7 xsl:importの誤った位置 |
例に使っている「書評一覧」の本のタイトルをもっと分かりやすい見出しにして、下線を引きたいとしましょう。既存のスタイルシートをコピーして一部を改変して新しいスタイルシートを作成することもできますが、保守性からいってそれは好ましくありません。将来、既存のスタイルシートに修正が入った場合、新しい方のスタイルシートにも同じ修正をいれなければならなくなるからです。むしろ既存のスタイルシートをいったん読込んだ後、改変したい部分だけを上書きする仕組みがあると便利です。xsl:import要素とxsl:include要素を組み合わせるとそれが実現できます。
まず改変したいテンプレートルールをリスト8に示すスタイルシート“modified.xsl”に集めます。それからリスト9のように、xsl:import要素で元のスタイルシート全体(リスト3)をいったん参照します。続いてxsl:include要素で改変する部分だけのスタイルシート(リスト8)を読込みます。
するとxsl:include要素で読込んだスタイルシート(リスト8)の方が優先度が高いため、重複するテンプレートはリスト8のテンプレートで上書きされたかのようになります。こうして保守性の高いスタイルシートを書くことができました。リスト9のスタイルシートの適用結果を画面2に示します。
<?xml version="1.0" encoding="Shift_jis"?> |
リスト8 改変する部分だけを集めたスタイルシート“modified.xsl” |
<?xml version="1.0" encoding="Shift_jis"?> |
リスト9 xsl:import要素とxsl:include要素を組み合わせたスタイルシート“web-sheet.xsl” |
今回は、XSLTのモジュール化手法を使って保守性の高いスタイルシートの書き方を説明しました。次回は、複数のXMLデータを処理する方法や相互参照の仕方を取り上げます。
本記事は、日本ユニテック発行のXMLテクノロジー総合情報誌「Digital Xpress」に掲載された、XSLT特集「XSLTの実力を探る!」の内容をもとに、加筆修正したものです。
Copyright © ITmedia, Inc. All Rights Reserved.