EXSLT / How To


このページでは、EXSLTで利用可能な拡張の使い方を解説する。

Contents

拡張の名前空間を定義する

EXSLTに記述されている拡張を使うために最初にするべきことは、EXSLTモジュールに関係する名前空間を定義することである。ユーザーは、スタイルシートのxsl:stylesheet要素で名前空間を宣言する必要がある。

宣言する必要がある名前空間は、使いたい関数に対応するモジュールの解説ページを見ればわかる。ただし一般的に、EXSLTモジュールの名前空間はある標準の規則にしたがって割り当てられている。

http://exslt.org/module-name

たとえば、Math?(数学)モジュールの名前空間は次のように宣言できる。

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math">
...
</xsl:stylesheet>

extension-element-prefixes属性を使うと、拡張の名前空間が結果ツリーに出力されるのを避けることができる。次を参照してほしい。

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
...
</xsl:stylesheet>

名前つきテンプレートを使う

実際のところ、名前つきテンプレートを使っても互換性の問題はまったくない。名前つきテンプレートはピュアなXSLT 1.0である。名前つきテンプレートを使えるかどうか判断するために、使用しているXSLTプロセッサやXSLTプロセッサの対応を気にかける必要はない。

EXSLTでは、それぞれの拡張関数とできるかぎり機能的に等価に近い名前つきテンプレートを提供するように努める。たとえば、math:min関数に関してはピュアなXSLT 1.0の名前つきテンプレートがmath.min.template.xslにある。もしこのテンプレートにだけ興味があるのなら、このスタイルシートをインポートするだけでよい。

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.min.template.xsl" />
...
</xsl:stylesheet>

するとxsl:call-templateでその名前つきテンプレートを呼び出せる。

<xsl:call-template name="math:min">
...
</xsl:call-template>

テンプレートに渡されるべき変数の名前や、それらの効果、それにデフォルト値は、等価な関数の解説ですべて説明されている。

拡張関数を使う

拡張関数を使うと、XPathに機能が加わる。一部の拡張関数は、特定のXSLTプロセッサに組み込まれているので、対応しているプロセッサを使っていれば拡張関数を使うことができる。その他の場合は、関数の実装がある場所をプロセッサに指示必要がある。

特定の実装を使う

このサイトで利用できる拡張関数の実装には2つの大きなカテゴリがある。

  • EXSLT - Functionsを使う実装
  • その他の言語を使う実装

EXSLT - Functionsで定義された実装を使う

関数の実装を定義する第1の方法は、exsl:functionをスタイルシートのトップレベルで使うことだ。これらの実装は、使用しているXSLTプロセッサがEXSLT - Functionsをサポートしている場合にのみ動作する。

これらのプロセッサのうちどれかを使っているのならば、EXSLT-Functionsスタイルシートを使用するスタイルシートにインポートするだけでよい。たとえば、math:minのEXSLT - Functions実装を使い、スタイルシートと同じディレクトリにコピーし、使う:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.min.function.xsl" />
...
</xsl:stylesheet>

他の言語で定義された実装を使う

第2の種類の実装は他の言語で定義されたものである。これには、XSLT 1.1のfunc:scriptを使う必要がある。これらの実装は、XSLTプロセッサがEXSLT - Functionsと関数の実装に使う言語の両方をサポートしている場合にのみ、動作する。

もしこれらのプロセッサのどれかを使っているのなら、xsl:script要素を次の属性と一緒に使う必要がある。

  • implements-prefix - モジュールの接頭辞
  • language - 実装言語
  • src - 実装ファイルの位置

たとえば、math:minのJavaScript?実装を使うには、使用するスタイルシートと同じディレクトリにコピーして使う:

<xsl:stylesheet version="1.1"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          xmlns:func="http://exslt.org/functions"
           extension-element-prefixes="math func">
<func:script implements-prefix="math" 
      language="exslt:javascript" 
      src="math.min.js" />
...
</xsl:stylesheet>

複数のfunc:script要素を使って、同一の拡張関数の複数の実装を異なる言語で定義することもできる。しかしながら、複数のfunc:script要素を使って、同一言語の異なる関数の実装を同一のモジュールに定義することはできない。implements-prefixとlanguageの値が同一のfunc:scriptを複数、同一のスタイルシートに定義するとエラーになる。もしたくさんの関数を同一のモジュールに定義して使いたいのならば、ファイルを結合して、結果をsrc属性で参照する必要がある。

Function-Levelパッケージを使う

ただ一つの特定の関数を使いたくて、しかしさまざまなプロセッサで使うことができるようにスタイルシートの互換性を保ちたい場合には、このサイトで提供する関数レベルパッケージを使うべきだ。これらのパッケージはそれぞれ特定の関数に利用できる実装すべてと、加えて、それらすべてを取り込んで利用可能にするスタイルシートを含んでいる。

スタイルシートで関数を利用できるようにする過程には、関数レベルパッケージのダウンロードと、解凍と、スタイルシートのインポートが含まれる。たとえば、math:min関数をスタイルシートで利用可能にするには、math.min.zipをダウンロードし、解凍し、math.min.xslを次のようにスタイルシートにインポートする必要がある。

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.min.xsl" />
...
</xsl:stylesheet>

こうすると、関数のあらゆるテンプレート実装も利用可能になる。

モジュールレベルパッケージを利用する

モジュールから複数の関数を利用する必要がある場合には、このサイトで提供している関係するモジュールレベルパッケージを使うべきだ。これらのパッケージはそれぞれ、ある特定のモジュールにあるすべての関数に対応する実装すべてと、加えてそれらを取り込み利用可能にするスタイルシート1つを含んでいる。

スタイルシート内で関数を利用可能にすることには、モジュールレベルパッケージのダウンロードと、解凍と、スタイルシートをパッケージからインポートすることが含まれる。たとえば、EXSLT - Mathモジュールをスタイルシートで利用可能にするには、math.zipをダウンロードし、解凍し、スタイルシートにmath.xslを次のようにインポートするべきだ。

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.xsl" />
...
</xsl:stylesheet>

拡張関数の互換性を保つ

拡張関数が、プロセッサに取り込まれるにせよ、ユーザー定義の拡張関数であるにせよ、その関数がサポートされているかどうか使う前にテストするのはよい練習だ。関数が使えるかどうかは、function-available関数を使えばテストできる。たとえば、math:minが利用可能か試すには、次のテストを使える。

function-available('math:min')

このサイトにある関数レベルおよびモジュールレベルパッケージは通常、関数と機能的に等しい名前つきテンプレートの定義を含んでいる。そのため、もしプロセッサがどの実装言語もサポートしていない場合にも、必要としている機能を得るために名前つきテンプレートに頼ることができる。たとえば、数値の組のうち最小のものを表示するときに最大限の互換性を確保するには、次のものを使うべきだ。

<xsl:choose>
   <xsl:when test="function-available('math:min')">
      <xsl:value-of select="math:min($values)" />
   </xsl:when>
   <xsl:otherwise>
      <xsl:call-template name="math:min">
         <xsl:with-param name="nodes" select="$values" />
      </xsl:call-template>
   </xsl:otherwise>
</xsl:choose>

拡張要素を使う

拡張要素を使うと、XSLTに機能が加わる。プロセッサが拡張要素の実装を使えるように一括して指示する標準の方法はない。その代わり、使用するプロセッサは拡張要素をあらかじめサポートしなければならない。

拡張要素を使うときにスタイルシートを分割しないためには、2つの方法がある。第1に、element-available関数を使うと要素が利用可能かどうか試すことができる。たとえば、grp:group要素が利用可能かためすには、次のコードを使える。

<xsl:choose>
   <xsl:when test="element-available('grp:group')">
      <grp:group ...>
         ...
      </grp:group>
   </xsl:when>
   <xsl:otherwise>
      <xsl:message terminate="yes">
         ERROR: Your processor does not support grp:group
      </xsl:message>
   </xsl:otherwise>
</xsl:choose>

一部のプロセッサ(特にSaxon)では、この方法は要素が命令に分類されているときにのみ動作する。つまり、最上位要素では動作しない。

2つ目の方法は、xsl:fallback要素を使うことだ。もし要素が拡張要素であることを宣言し(この宣言はxsl:stylesheetのextension-element-prefixes属性にある接頭辞で名前空間を与えることでできる)、プロセッサがテンプレートの中でその要素に遭遇し、しかしプロセッサはその要素のあらかじめ組み込まれた実装がない場合、プロセッサはfallbackをする。Fallbackには、拡張要素の中にxsl:fallback要素を探すことと、その内容のインスタンスを作成することが含まれる。たとえば、次のコードはgrp:group拡張要素を使おうとし、拡張要素が存在しない場合にはエラーメッセージを発する。

<grp:group ...>
   ...
   <xsl:fallback>
      <xsl:message terminate="yes">
         ERROR: Your processor does not support grp:group
      </xsl:message>
   </xsl:fallback>
</grp:group>

これは拡張要素がテンプレート内で使われている場合にのみ動作する。