前回のヒント(参考文献をご覧ください)では、スタイルシートを使って、異なるXMLドキュメントを結合する方法について説明しました。例を示すために、4つのXMLドキュメントが最終的に組み合わされて1つのWebページとして構成されるフォトギャラリーを使いました。このテクニックはログファイル(日々のログを結合した月報)や目次(幾つかの章を結合した1つの目次)などにも役立ちます。
今回のヒントでは異なるアプローチをします。1つのXMLドキュメントがあり、出力すると数ページにわたる時、あなたはどうしますか。より速くダウンロードするために、長いドキュメントをより短く分断するのではないでしょうか。
リスト1の文書は、解説付きの4枚の写真からなる小さなフォトギャラリーです。あなたの課題は、小規模なWebサイトに文書をデザインすることです。ダウンロードを速くするためには、各写真をそれぞれのページに置くべきです。難しいのは、写真があるページ毎にオリジナルの文章を分割することです。
ページを分割するにあたって、良い話と悪い話があります。良い話は、一般的なXSLTプロセッサーを使って、好きなだけドキュメントを分割できることです。悪い話は、この機能が(まだ)標準ではないことです。ご存知のように、XSLTプロセッサー毎に異なったインプリメントになっています。ただ幸いなことに、その差異は表面的なものです。
リスト2はフォトギャラリーを公開するためのスタイルシートです。gl:photoのテンプレートに注目してください。このテンプレートは、xalan:redirectインストラクションによって、分割されたHTMLページを作成してそれらを保存します。このスタイルシートはJDK1.4.1によってテストされ、JDK XLSTプロセッサ、Xalan単体(Apache XalanはJAXPのリファレンス・インプリメントです)のいずれかで動作します。
リスト2:jdk.xsl--JDK1.4(またはXalan)用のスタイルシート
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gl="http://ananas.org/2003/tips/gallery"
xmlns:xalan="org.apache.xalan.xslt.extensions.Redirect"
extension-element-prefixes="xalan">
<xsl:output method="html"/>
<xsl:template match="gl:gallery">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<h1><xsl:value-of select="gl:title"/></h1>
<p>The photos are <a href="photo-0.html">here</a>.</p>
</body>
</html>
<xsl:apply-templates select="gl:photo"/>
</xsl:template>
<xsl:template match="gl:photo">
<xalan:write select="concat('photo-',position(),'.html')">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<img src="{gl:image}" align="left"/>
<h1><xsl:value-of select="gl:title"/></h1>
<p><xsl:value-of select="gl:date"/></p>
<p><xsl:value-of select="gl:description"/></p>
<p>
<xsl:if test="preceding-sibling::gl:photo">
<a href="photo-{position() - 1}.html">Previous</a>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="following-sibling::gl:photo">
<a href="photo-{position() + 1}.html">Next</a>
</xsl:if>
</p>
</body>
</html>
</xalan:write>
</xsl:template>
</xsl:stylesheet>
|
ソースコード(参考文献を参照してください)は、このコードをテストするためにドキュメント、スタイル・シートおよび小さなJavaアプリケーションを含んでいます。JDK1.4上で、動作することを確認してください。
xalan:redirectは対象要素の内容を別々のファイルにセーブするようプロセッサーに伝えます。ファイル名は、select属性で指定します。この例では、スタイルシートが写真の番号(正確にはその位置)をphoto-xに付加してファイル名を決定します。ファイルはphoto-1.html、photo-2.html、photo-3.html、photo-4.htmlになります。
残念なことに、xalan:redirectは、標準の一部ではありませんので、他のプロセッサーはそれを認識しません。xalan:redirectは拡張機能としてインプリメントされます。拡張であることを宣言するために、最初にネーム・スペースとしてorg.apache.xalan.xslt.extensions.Redirect URIを宣言しなければなりません。明らかに、org.apache.xalan.xslt.extensions.Redirectは正当なURIではありませんが、xalanはまだそれを認識します。次に拡張機能のネーム・スペースをextension-element-prefixes属性で宣言しなければなりません。ネーム・スペースの宣言およびextension-element-prefixes属性は、共にxsl:stylesheet要素内に記述する必要があります。
Xalanは優れたプロセッサーです。しかし、もしあなたが他のプロセッサーを使いたいとしたらどうでしょうか?今のところ、あなたの好みのXSLTプロセッサーの資料を丹念に調べ、同等の拡張機能を探し出さなければなりません。私の知りうる限りでは、全てのXSLTプロセッサーが、複数文書の出力をサポートするために、少なくとも1つは拡張機能を提供しています。
例えば、あなたがMichael Kayの優れたSaxonプロセッサーを使用したいと思うなら、xalan:redirectの代わりにsaxon:outputを使うように、gl:photo のテンプレートを書き直すことになるでしょう。saxon:outputはxalan:redirectに非常に似ているので、最小限の変更で対応できます。リスト3はリスト2のSaxonバージョンです(拡張機能のために定義したネーム・スペースSaxonの使い方に注意してください)。
リスト3:saxon.xsl -Saxon用のスタイルシート
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gl="http://ananas.org/2003/tips/gallery"
xmlns:saxon="http://icl.com/saxon" extension-element-prefixes="saxon">
<xsl:output method="html"/>
<xsl:template match="gl:gallery">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<h1><xsl:value-of select="gl:title"/></h1>
<p>The photos are <a href="photo-1.html">here</a>.</p>
</body>
</html>
<xsl:apply-templates select="gl:photo"/>
</xsl:template>
<xsl:template match="gl:photo">
<saxon:output href="photo-{position()}.html">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<img src="{gl:image}" align="left"/>
<h1><xsl:value-of select="gl:title"/></h1>
<p><xsl:value-of select="gl:date"/></p>
<p><xsl:value-of select="gl:description"/></p>
<p>
<xsl:if test="preceding-sibling::gl:photo">
<a href="photo-{position() - 1}.html">Previous</a>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="following-sibling::gl:photo">
<a href="photo-{position() + 1}.html">Next</a>
</xsl:if>
</p>
</body>
</html>
</saxon:output>
</xsl:template>
</xsl:stylesheet>
|
W3Cで現在開発中のXLST2.0では、多重出力を生成する標準仕様を定義しています。実際のところ、それはxalan:redirectやsaxon:outputに非常によく似ていますが、標準的な名前が与えられました。XSLT2.0の2003年5月2日のドラフト(執筆時点で最新のドラフト)で、xsl:result-documentインストラクションとなっています。リスト4は、その使用法を示したものです。この例がversion属性によって示されるように、XSLT2.0のスタイルシートであることに注意してください。
リスト4:xsl2.xsl --XSLT2.0スタイルシートで新標準を利用する
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gl="http://ananas.org/2003/tips/gallery">
<xsl:output method="html"/>
<xsl:template match="gl:gallery">
<xsl:apply-templates select="gl:photo"/>
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<h1><xsl:value-of select="gl:title"/></h1>
<p>The photos are <a href="photo-0.html">here</a>.</p>
</body>
</html>
</xsl:template>
<xsl:template match="gl:photo">
<xsl:result-document href="photo-{position()}.html">
<html>
<head><title><xsl:value-of select="gl:title"/></title></head>
<body>
<img src="{gl:image}" align="left"/>
<h1><xsl:value-of select="gl:title"/></h1>
<p><xsl:value-of select="gl:date"/></p>
<p><xsl:value-of select="gl:description"/></p>
<p>
<xsl:if test="preceding-sibling::gl:photo">
<a href="photo-{position() - 1}.html">Previous</a>
<xsl:text> </xsl:text>
</xsl:if>
<xsl:if test="following-sibling::gl:photo">
<a href="photo-{position() + 1}.html">Next</a>
</xsl:if>
</p>
</body>
</html>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>
|
Webサイトを公開する場合、1つのXMLドキュメントを幾つかのより小さなファイルに分断することは、一般的にダウンロードの速度向上などに役立ちます。さらに、フレーム上で動作する時にも役立ちます。多重出力は画面表示に限定されません。私は電子商取引プロジェクトの中で、巨大なデータベース出力をより小さくして、管理しやすいファイルにするためにも、この技術を使用しました。
- 本記事のソースコードは、こちらからダウンロードできます。
- このヒントとは逆に複数のXMLドキュメントを結合させる方法について述べている「ヒント: XSLTを使って文書を結合する方法」(developerWorks、2003年5月)をお読みください。
- XSLTコーディングの優れたリソースをXMLPitstop.com.でご確認ください。
- JDK1.4はIBM's developer kitsのWebサイト、またはSunからダウンロードできます。同じくXalan(JDKに埋め込まれたXSLTプロセッサー)は、Apacheから別個にダウンロードできます。
- Michael Kayの Saxonプロセッサーは、SourceForgeから利用可能です。お試しください。
- developerWorks のXMLゾーンには、XMLに関する記事が多数掲載されています。
-
XML及び関連技術においてIBM認証開発者になる方法についてはこちらを参照してください。

Benoit Marchal氏は、ベルギーのナミュールを拠点にしたコンサルタントおよび著述家です。彼の著作には、 XML by Example(Que社、邦訳: インプレス社「実例で学ぶXML」。間もなく第2版が出版される予定です)、 Applied XML Solutions および XML and the Enterprise があります。また、Gamelanのコラムや、developerWorks XML zoneのコラムWorking XML の著者でもあります。最新プロジェクトの詳細については、www.marchal.com をご覧ください。