この文書は、XSL Transformations (XSLT) 勧告の翻訳です。正式な版は、W3Cのサイトにある英語版であり、この翻訳ではありません。この翻訳は原文と技術的に等価なことを意図していますが、翻訳上の誤りが存在する可能性があります。

原文はつぎのURLで参照することができます。 http://www.w3.org/TR/1999/REC-xslt-19991116

翻訳責任:インフォテリア株式会社 最終更新日:2000年5月1日(更新履歴)
この翻訳に関するコメントは dev_request@infoteria.co.jp まで

W3C

XSL Transformations (XSLT)
バージョン 1.0

W3C 勧告 1999 年 11月 16 日

このバージョン:
http://www.w3.org/TR/1999/REC-xslt-19991116
(XML 版または HTML 版)
最新のバージョン:
http://www.w3.org/TR/xslt
以前のバージョン:
http://www.w3.org/TR/1999/PR-xslt-19991008
http://www.w3.org/1999/08/WD-xslt-19990813
http://www.w3.org/1999/07/WD-xslt-19990709
http://www.w3.org/TR/1999/WD-xslt-19990421
http://www.w3.org/TR/1998/WD-xsl-19981216
http://www.w3.org/TR/1998/WD-xsl-19980818
編者:
James Clark

要約

この仕様は XSLT のシンタックスとセマンティクスを定義する。XSLT とは、XML ドキュメントを別の XML ドキュメントに変換するための言語である。

XSLT は、XML 用のスタイルシート言語である XSL の一部として使用するために設計された。 XSL は XSLT の他に、フォーマットを指定するための XML のボキャブラリも含む。 XSL は XML ドキュメントのスタイルを指定する際に、そのドキュメントをフォーマットボキャブラリを使用する別の XML ドキュメントへ変換する方法を、XSLT を使用して記述する。

XSLT は XSL から独立して使用できるようにも設計されている。しかし、XSLT は 完全に汎用的な XML 変換用言語として使用するために設計されたわけではない。 むしろ設計の主眼は、XSL の一部として XSLT を 使用する際に必要となる変換処理を行うことにある。

この文書の状態

この文書は、W3C メンバおよびその他の関係者が評価し、W3C 勧告として担当の責任者が承認したものである。 今後変更される可能性はなく、他の文書において参考資料として使用したり、あるいは基準となる参考文献として引用することができる。 勧告の策定にあたって W3C が担う役割は、この仕様を広く普及させることにある。 これにより Web の機能性と相互運用性を向上させることができる。

この仕様に関する正誤表は http://www.w3.org/1999/11/REC-xslt-19991116-errata で参照できる。

この仕様に関するコメントの宛先は xsl-editors@w3.org である。なお、コメントのアーカイブも利用できる。 XSL Transformationsを含む XSL に関する公開ディスカッションは、XSL-List メーリングリストで行われている。

この仕様の基準とバージョンは英語版のみであるが、 翻訳版を http://www.w3.org/Style/XSL/translations.html で参照できる。

W3C 勧告の一覧、およびその他の技術文書は http://www.w3.org/TR で入手できる。

この仕様は W3C のスタイルに関する活動 (W3C Style activity) の一環として作成されたものである。

目次

1 一般事項
2 スタイルシートの構造
    2.1 XSLT ネームスペース
    2.2 スタイルシートのエレメント
    2.3 スタイルシートとしてのリテラル結果エレメント
    2.4 修飾名
    2.5 将来のバージョンと互換性のある処理
    2.6 スタイルシートの結合
        2.6.1 スタイルシートのインクルード
        2.6.2 スタイルシートのインポート
    2.7 スタイルシートの埋め込み
3 データモデル
    3.1 ルートノードの子
    3.2 ベース URI 
    3.3 パース対象外エンティティ
    3.4 空白の削除
4
5 テンプレートルール
    5.1 処理モデル
    5.2 パターン
    5.3 テンプレートルールの定義
    5.4 テンプレートルールの適用
    5.5 テンプレートルールの競合解決
    5.6 テンプレートルールのオーバーライド(上書き)
    5.7 モード
    5.8 組み込みテンプレートルール
6 名前付きテンプレート
7 結果ツリーの生成
    7.1 エレメントとアトリビュートの生成
        7.1.1 リテラル結果エレメント
        7.1.2 xsl:element を用いたエレメントの生成
        7.1.3 xsl:attribute を用いたエレメントの生成
        7.1.4 名前付けされたアトリビュートの集合
    7.2 テキストの生成
    7.3 プロセッシングインストラクションの生成
    7.4 コメントの生成
    7.5 コピー
    7.6 テキストの動的生成
        7.6.1 xsl:value-of を使用したテキストの生成
        7.6.2 アトリビュート値テンプレート
    7.7 番号付け
        7.7.1 数値から文字列への変換のアトリビュート
8 繰り返し
9 条件付き処理
    9.1 xsl:if を用いた条件付き処理
    9.2 xsl:choose を用いた条件付き処理
10 ソート
11 変数とパラメータ
    11.1 結果ツリーフラグメント
    11.2 変数とパラメータの値
    11.3 xsl:copy-of を用いた変数とパラメータの値の使用
    11.4 トップレベルの変数とパラメータ
    11.5 テンプレート内部の変数とパラメータ
    11.6 テンプレートへのパラメータの引き渡し
12 追加の関数
    12.1 複数のソースドキュメント
    12.2 キー
    12.3 数値のフォーマット
    12.4 その他の追加の関数
13 メッセージ
14 拡張
    14.1 拡張エレメント
    14.2 拡張関数
15 フォールバック
16 出力
    16.1 XML 出力メソッド
    16.2 HTML 出力メソッド
    16.3 テキスト出力メソッド
    16.4 出力エスケープの無効化
17 適合性
18 ノテーション

付録

A 参考文献
    A.1 基準となる参考文献
    A.2 その他の参考文献
B エレメントのシンタックスの要約
C XSLT スタイルシート用 DTD フラグメント(規定外)
D (規定外)
    D.1 文書例
    D.2 データ例
E 謝辞(規定外)
F 勧告案からの変更点(規定外)
G XSLT の今後のバージョンについて検討中の機能(規定外)

1 一般事項

この仕様は XSLT 言語のシンタックスとセマンティクスを定義するものである。 XSLT 言語による変換は、XML ネームスペース勧告 (Namespaces in XML Recommendation)[XML Names] に適合したウェルフォームド XML ドキュメント [XML] で表わされる。その XML ドキュメントには、XSLT で定義されているエレメントと XSLT では定義されていないエレメントのどちらも使用できる。 XSLT で定義されているエレメントは、特定の XML ネームスペースに所属することにより区別される ([2.1 XSLT ネームスペース] を参照)。この仕様では、この特定の XML ネームスペースを XSLT ネームスペースと呼ぶ。 従って、この仕様は XSLT ネームスペースのシンタックスとセマンティクスを定義するものである。

XSLT が表現する変換では、ソースツリーから結果ツリーへの変換処理上のルールを記述している。 この変換は、パターンをテンプレートに関連付けることによって実現する。 パターンはソースツリー内のエレメントと照合され、 テンプレートはインスタンス化されて結果ツリーの一部を生成する。 結果ツリーはソースツリーから独立している。 結果ツリーの構造は、ソースツリーの構造とまったく異なるものになることもある。 結果ツリーを構築する際には、ソースツリーのエレメントをフィルタしたり、エレメントの順序を変更したりできる。また、任意の構造を付加することも可能である。

XSLT が表現する変換をスタイルシートと呼ぶ。その理由は、XSLT を XSL のフォーマット用言語要素に変換する際に、この変換がスタイルシートとして機能するためである。

この文書では、XSLT スタイルシートを XML ドキュメントに関連付ける方法を規定しない。 XSL プロセッサは、[XML Stylesheet] で記述しているメカニズムをサポートしていることが望ましい。 このメカニズムまたは他のメカニズムが、1つの XML ドキュメントに同時に適用される複数の XSLT スタイルシートのシーケンスを生成した場合は、そのシーケンスに含まれる各メンバを順序どおりインポートした1つのスタイルシートを適用したときと同じ結果が得られるべきである ([2.6.2 スタイルシートのインポート] を参照)。

スタイルシートはテンプレートルールの集合を含んでいる。 テンプレートルールは2つの部分から成る。 1つはパターンであり、ソースツリーのノードと照合される。もう1つはインスタンス化が可能なテンプレートであり、結果ツリーの一部を構築する。 このような構成により、類似したソースツリー構造を持つ多様な文書に対してスタイルシートの適用が可能になる。

テンプレートは特定のソースエレメントに対してインスタンス化され、結果ツリーの一部を生成する。 テンプレートはリテラル結果エレメントの構造となるエレメントを含むことができる。 また、結果ツリーフラグメントを生成するインストラクションとなる XSLT ネームスペースのエレメントを含むことも可能である。 テンプレートをインスタンス化すると、各インストラクションが実行され、生成された結果ツリーフラグメントによる置き換えが行われる。 インストラクションは、子孫ソースエレメントを選択して処理することもある。子孫エレメントの処理では、適用可能なテンプレートルールを見つけ、そのテンプレートをインスタンス化することにより、結果ツリーフラグメントを生成する。 ただし、エレメントを処理するのは、インストラクションを実行により選択された場合だけである。 結果ツリーはルートノード用のテンプレートルールを見つけ、そのテンプレートをインスタンス化することにより構築される。

適用できるテンプレートルールの検索中に、所定のエレメントに対応できるパターンを持つテンプレートルールが複数見つかる場合がある。 このような場合でも、適用されるテンプレートルールは1つだけである。適用するテンプレートルールの決定方法については、[5.5 テンプレートルール競合時の解決] で解説している。

テンプレートは、1つだけでも強力な処理能力を持っている。たとえば、好きなだけ複雑な構造を生成することや、ソースツリー内の任意の場所から文字列の値を取り出すこと、ソースツリー内のエレメント出現回数に合わせて繰り返し構造を生成することなどが可能である。 結果ツリーの構造がソースツリーの構造から独立している単純な変換であれば、テンプレート1つだけでスタイルシートを構成することが可能であり、そのようなスタイルシートは完全な結果ツリーを得られるテンプレートとして機能する。 データを表わす XML ドキュメントの変換は、このような形式である場合が多い ([D.2 データ例] を参照)。 XSLT は、このようなスタイルシート用に簡略化したシンタックスを認めている ([2.3 スタイルシートとしてのリテラル結果エレメント] を参照)。

テンプレートをインスタンス化する際には、常にカレントノードカレントノードリストを基準としてインスタンス化される。 カレントノードは、常にカレントノードリストのメンバである。 XSLT の操作の多くは、カレントノードと関連している。 カレントノードリストやカレントノードを変更するインストラクションは数種類しか存在しない ([5 テンプレートルール] および [8 繰り返し] を参照)。これらのインストラクションのいずれかをインスタンス化する際には、カレントノードリストは新しいノードのリストに変更され、新リストの各メンバが順番にカレントノードになる。インストラクションのインスタンス生成が終わると、カレントノードとカレントノードリストの内容は、インストラクションがインスタンス化される前の状態に戻る。

XSLT は [XPath] で定義された式言語を利用し、処理対象エレメントの選択、条件付きの処理、およびテキストの生成を行う。

XSLT は言語の拡張用に2つの「フック」を備えている。1つはテンプレートで使用するインストラクションエレメントの集合を拡張するフックであり、もう1つは XPath の式で使用する関数の集合を拡張するフックである。 これらのフックはどちらも XML ネームスペースを基盤としている。 このバージョンの XSLT では、フックの実装に関するメカニズムを定義していない。 [14 拡張] を参照のこと。

注: XSL 作業グループでは、この仕様の今後のバージョンまたは独立した仕様において、このメカニズムを定義する予定である。

XSLT で定義したエレメントのシンタックスを記述するためのエレメントシンタックス要約用ノテーションについては、[18 ノテーション] で解説している。

XSLT スタイルシートには、MIME メディア型の text/xml および application/xml[RFC2376] を使用すべきである。 XSLT スタイルシートには、あるメディア型が明示的に登録されるかもしれない。その場合、登録したメディア型も使用できる。

2 スタイルシートの構造

2.1 XSLT ネームスペース

XSLT ネームスペースの URI は http://www.w3.org/1999/XSL/Transform である。

注: URI 内の 1999 は、W3C がこの URI を割り当てた年度を示している。 使用する XSLT のバージョンは、この数字ではなくアトリビュートにより指定される ([2.2 スタイルシートのエレメント] および [2.3 スタイルシートとしてのリテラル結果エレメント] を参照)。

XSLT プロセッサは XML ネームスペースのメカニズム [XML Names] を使用し、XML ネームスペースのエレメントとアトリビュートを認識しなければならない (must)。 XSLT ネームスペースのエレメントは、ソースドキュメント内ではなく、スタイルシート内でのみ認識される。 XSLT で定義したエレメントの全リストは [B エレメントのシンタックスの要約] に記載してある。 ベンダはエレメントやアトリビュートを追加し、XSLT ネームスペースを拡張してはならない (must)。 拡張を行う場所は XSLT ネームスペースではなく、別のネームスペース内でなければならない (must)。 インストラクション用エレメントを追加する際に使用するネームスペースは、[14.1 拡張エレメント] で解説している拡張エレメントのメカニズムを利用して識別されなければならない (must)。

この仕様では、XSLT ネームスペース内のエレメントを参照するプレフィックスとして xsl: を使用する。XSLT スタイルシートでは、そのプレフィックスを XSLT ネームスペースの URI にバインドするネームスペース宣言が存在すれば、どのようなプレフィックスも使用できる。

XSLT ネームスペースのエレメントは、アトリビュートの展開された名前 (expanded-name) が null 以外のネームスペース URI を持つ場合に限り、XSLT ネームスペースに所属しないアトリビュートを持ってもよい。 このようなアトリビュートが存在するために、XSLT エレメントとこの文書で定義する関数の動作を変更してはならない (must)。 従って、XSLT プロセッサはこのようなアトリビュートをいつでも無視できるし、そのネームスペース URI を認識できない場合には、エラーを生成せずにこれらのアトリビュートを無視しなければならない (must)。 このようなアトリビュートはユニークな識別子、最適化のヒント、ドキュメンテイションなどを指定できる。

このドキュメントでエレメント用に定義したアトリビュート以外に、null のネームスペース URI を持つ展開された名前が付けられたアトリビュート (プレフィックスのない名前が付けられたアトリビュート) が XSLT ネームスペースのエレメントに含まれる場合はエラーである。

注: XSLT のエレメント、アトリビュート、および関数の名前に関する表記規則は、小文字だけで名前を付けること、単語はハイフン (-) で区切ること、そして略語は XML や HTML などの関連言語のシンタックス内で記述済みの場合のみ使用すること、である。

2.2 スタイルシートのエレメント

<xsl:stylesheet
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  
</xsl:stylesheet>

<xsl:transform
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  
</xsl:transform>

スタイルシートは、XML ドキュメント内で xsl:stylesheet エレメントとして表される。 xsl:transform は、xsl:stylesheet の同義語として使用できる。

xsl:stylesheet エレメントには version アトリビュートを記述し、スタイルシートに必要な XSLT のバージョンを示さなければならない (must)。 このバージョンの XSLT では、アトリビュート値は 1.0 であるべきである。 この値が 1.0 以外の場合は、将来のバージョンと互換性のある (forwards-compatible) 処理モードが有効になる ([2.5 将来のバージョンと互換性のある処理] を参照)。

xsl:stylesheet エレメントは、以下の型のエレメントを含むことができる。

xsl:stylesheet エレメントの子として現れるエレメントは、トップレベル (top-level) エレメントと呼ばれる。

以降にスタイルシートの構造の例を示す。省略記号 (...) のある場所は、アトリビュート値あるいはコンテンツが省略されていることを示している。 この例では、使用可能なエレメント型をそれぞれ1つずつ記述しているが、スタイルシートにはこれらのエレメントを1つも含めなくても、複数含めてもよい。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="..."/>
  <xsl:include href="..."/>
  <xsl:strip-space elements="..."/>
  
  <xsl:preserve-space elements="..."/>
  <xsl:output method="..."/>
  <xsl:key name="..." match="..." use="..."/>
  <xsl:decimal-format name="..."/>
  <xsl:namespace-alias stylesheet-prefix="..." result-prefix="..."/>
  <xsl:attribute-set name="...">
    ...
  </xsl:attribute-set>
  <xsl:variable name="...">...</xsl:variable>
  <xsl:param name="...">...</xsl:param>
  <xsl:template match="...">
    ...
  </xsl:template>
  <xsl:template name="...">
    ...
  </xsl:template>
</xsl:stylesheet>

xsl:stylesheet エレメントの子の出現順序は、xsl:import エレメントとエラー回復の場合を除いて重要ではない。ユーザーはエレメントを自由に並べることができる。また、スタイルシートの生成ツールもエレメントの出現順序の制御機能を持つ必要はない。

さらに、エレメントの展開された名前が null 以外のネームスペース URI を持つ場合に限り、xsl:stylesheet エレメントは XSLT ネームスペースに所属しないエレメントを含んでもよい。 このようなトップレベルエレメントが存在しても、この文書で定義されたXSLT エレメントと関数の動作を変更してはならない (must)。たとえば、競合を解決するために異なるルールを使用する目的でトップレベルエレメントに xsl:apply-templates を指定することは許されない。 従って、XSLT プロセッサはこのようなトップレベルエレメントをいつでも無視できるし、ネームスペース URI を認識できない場合には、エラーを生成せずにこれらのトップレベルエレメントを無視しなければならない (must)。 これらのエレメントは以下のようなデータを提供できる。

2.3 スタイルシートとしてのリテラル結果エレメント

ルートノード用のテンプレート1つだけで構成するスタイルシートでは、簡略化したシンタックスを使用できる。 このスタイルシートは、リテラル結果エレメントのみで構成することができる ([7.1.1 リテラル結果エレメント] を参照)。 このようなスタイルシートは、そのリテラル結果エレメントを含む、マッチパターンが / のテンプレートルールを1つだけを含む xsl:stylesheet エレメントを持つスタイルシートと同等である。 以下に例を示す。

<html xsl:version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns="http://www.w3.org/TR/xhtml1/strict">
  <head>
    <title>Expense Report Summary</title>
  </head>
  <body>
    <p>Total Amount: <xsl:value-of select="expense-report/total"/></p>
  </body>
</html>

この記述は以下の記述と同じ意味を持つ。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/TR/xhtml1/strict">
<xsl:template match="/">
<html>
  <head>
    <title>Expense Report Summary</title>
  </head>
  <body>
    <p>Total Amount: <xsl:value-of select="expense-report/total"/></p>
  </body>
</html>
</xsl:template>
</xsl:stylesheet>

スタイルシートのドキュメントエレメントであるリテラル結果エレメントには、スタイルシートに必要な XSLT のバージョンを示す xsl:version アトリビュートを指定しなければならない (must)。このバージョンの XSLT では、アトリビュート値は 1.0 であるべきである。また、この値は Number でなければならない (must)。その他のリテラル結果エレメントについても、xsl:version アトリビュートを指定できる。 xsl:version アトリビュートの値が 1.0 以外の場合は、将来のバージョンと互換性のある (forwards-compatible) 処理モードが有効になる ([2.5 将来のバージョンと互換性のある処理] を参照)。

スタイルシートとして使用するリテラル結果エレメントのコンテンツとして許されるのは、スタイルシート内にリテラル結果エレメントが使われた場合と同様である。 従って、スタイルシートとして使用するリテラル結果エレメントは、トップレベルエレメントを含むことはできない。

XML ドキュメントを処理する際に、XSLT プロセッサを使用して XSLT スタイルシートとして処理する必要があるかどうかは、XML ドキュメント自体を調査しなければわからない場合もある。 簡略化したシンタックスを使用する場合には、この処理がより難しくなる。

注: たとえば、別の XML 言語 (AXL) もドキュメントエレメント上に axl:version と指定し、ある XML ドキュメントが AXL プロセッサによる処理が必要な AXL ドキュメントであることを指示している可能性もある。1つの文書に axl:version アトリビュートと xsl:version アトリビュートの両者が含まれていると、その文書を XSLT プロセッサと AXL プロセッサのどちらで処理すべきかあいまいになる。

そのため、このような状況で使われる可能性がある XSLT スタイルシートには、簡略化したシンタックスを使用すべきではない。 たとえば、このような状況は、MIME メディア型を使ってメッセージの処理方法を決定する受信者に対して、text/xml または application/xml の MIME メディア型を持つメッセージとして XSLT スタイルシートが送信された場合に発生し得る。

2.4 修飾名

内部 XSLT オブジェクトの名前は、QName として指定される。具体的には、名前付きテンプレート ([6 名前付きテンプレート] を参照)、モード ([5.7 モード] を参照)、アトリビュートの集合 ([7.1.4 名前付きアトリビュートの集合] を参照)、キー ([12.2 キー] を参照)、デシマルフォーマット (decimal-format) ([12.3 数値のフォーマット] を参照)、変数、またはパラメータ ([11 変数とパラメータ]) などである。 名前にプレフィックスがある場合、そのプレフィックスは、名前が現れるアトリビュートに対して有効なネームスペース宣言を使って URI リファレンスに展開される。 展開された名前 (expanded-name) は、名前のローカルパートと URI リファレンス (null もありうる) から構成され、オブジェクトの名前に使用される。 デフォルトのネームスペースは、プレフィックスのない名前には使用されない

2.5 将来のバージョンと互換性のある処理

エレメントは次のいずれかの場合に該当すると、自分自身とそのアトリビュート、および自分の子孫とそれらのアトリビュートに対して将来のバージョンと互換性のある処理モードを有効にする。version アトリビュートの値が 1.0 以外の xsl:stylesheet エレメントの場合、リテラル結果エレメントであって xsl:version アトリビュートを持ち、その値が 1.0 以外のエレメントの場合、あるいは、リテラル結果エレメントであって xsl:version アトリビュートを持たず、簡略化したシンタックス ([2.3 スタイルシートとしてのリテラル結果エレメント] を参照) を使用するスタイルシートのドキュメントエレメントの場合である。 リテラル結果エレメントが xsl:version アトリビュートを持ち、その値が 1.0 の場合は、自分自身とそのアトリビュート、および自分の子孫とそのアトリビュートに対する将来のバージョンと互換性のある処理モードは無効になる。

将来のバージョンと互換性のある処理モードでエレメントを処理すると、以下の結果が得られる。

従って、以下のスタイルシートには、この仕様で定義していない XSLT ネームスペースのエレメントが含まれるが、XSLT 1.0 プロセッサであれば、このスタイルシートをエラーを起こさず処理できなければならない (must)。

<xsl:stylesheet version="1.1"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="system-property('xsl:version') >= 1.1">
        <xsl:exciting-new-1.1-feature/>
      </xsl:when>
      <xsl:otherwise>
        <html>
        <head>
          <title>XSLT 1.1 required</title>
        </head>
        <body>
          <p>Sorry, this stylesheet requires XSLT 1.1.</p>
        </body>
        </html>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>
注: あるスタイルシートが 1.0 以降のバージョンの XSL に導入されているトップレベルエレメントに完全に依存する場合、そのスタイルシートの xsl:message エレメントに terminate="yes" ([13 メッセージ] を参照) を指定すると、以前のバージョンの XSL を実装する XSLT プロセッサがトップレベルエレメントを無視するときには必ず警告を発するようにできる。 以下に例を示す。
<xsl:stylesheet version="1.5"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:important-new-1.1-declaration/>
  <xsl:template match="/">
    <xsl:choose>
      <xsl:when test="system-property('xsl:version') &lt; 1.1">
        <xsl:message terminate="yes">
          <xsl:text>Sorry, this stylesheet requires XSLT 1.1.</xsl:text>
        </xsl:message>
      </xsl:when>
      <xsl:otherwise>
        ...
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  ...
</xsl:stylesheet>

あるが将来のバージョンと互換性のあるモードで処理されるアトリビュートに現れる場合、XSLT プロセッサは式のエラーから次のように回復しなければならない (must)。

2.6 スタイルシートの結合

XSLT には、スタイルシートを結合するメカニズムが2種類ある。

2.6.1 スタイルシートのインクルード


<xsl:include
  href = uri-reference />

XSLT スタイルシートは xsl:include エレメントを記述することにより、別の XSLT スタイルシートを取り込むことができる。xsl:include エレメントは href アトリビュートを持っている。このアトリビュート値は、インクルードするスタイルシートを識別するための URI リファレンスである。相対 URI は、xsl:include エレメントのベース URIを基準に解決される ([3.2 ベース URI] を参照)。

xsl:include エレメントは、トップレベルエレメントとしてのみ使用できる。

このインクルード処理は、XML のツリーレベルで行われる。href アトリビュートの値によって位置を特定したリソースは、XML ドキュメントとしてパースされ、XML ドキュメント側の xsl:stylesheet エレメントの子が、インクルードするドキュメント側の xsl:include エレメントを置き換える。 テンプレートのルールや定義が含まれていても、それらの処理方法には影響を与えない。

インクルードされるスタイルシートでは、[2.3 スタイルシートとしてのリテラル結果エレメント] で解説している簡略化したシンタックスを使用してもよい。 インクルードされるスタイルシートは、xsl:stylesheet エレメントと同様に扱われる。

スタイルシートが自分自身を直接的または間接的にインクルードする場合は、エラーとなる。

注: スタイルシートを複数回インクルードする場合、定義の重複によってエラーを発生する可能性がある。 間接的にインクルードされている場合には、このような複数のインクルードは、より見つけづらくなる。 たとえば、スタイルシート B がスタイルシート A をインクルードし、スタイルシート C がスタイルシート A をインクルードしてから、スタイルシート D がスタイルシート B とスタイルシート C の両者をインクルードすると、AD 内に間接的に2回インクルードされることになる。 BC、および D のすべてが独立したスタイルシートとして使用される場合は、A からインクルードした内容を除くすべての B の内容を別のスタイルシート B' に分離し、BB'A をインクルードする形に変更する。同様に C を分離してから、DAB'、および C' をインクルードするように変更することで、エラーを回避できる。

2.6.2 スタイルシートのインポート

<xsl:import
  href = uri-reference />

XSLT スタイルシートに、xsl:import エレメントを使用して別の XSLT スタイルシートをインポートしてもよい。スタイルシートのインポートは、スタイルシートのインクルード ([2.6.1 スタイルシートのインクルード] を参照) と同様だが、インポートする側のスタイルシートに含まれる定義とテンプレートルールが、インポートされる側のスタイルシートに含まれる定義とテンプレートルールより優先される点が異なる。この点に関する詳細を次に解説する。 xsl:import エレメントは、href アトリビュートを持っている。このアトリビュート値は、インポートするスタイルシートを識別するための URI リファレンスである。 相対 URI は、xsl:import エレメントのベース URIを基準に解決される ([3.2 ベース URI] を参照)。

xsl:import エレメントは、トップレベルエレメントとしてのみ使用できる。xsl:import エレメントは、xsl:include エレメントを含め、xsl:stylesheet エレメントのすべての子よりも優先されなければならない (must)。 xsl:include でスタイルシートをインクルードした場合、インクルードされるドキュメント内の xsl:import エレメントはすべて、インクルードする側のドキュメント内に既存のすべての xsl:import エレメントの後ろに移動される。

以下に例を示す。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="article.xsl"/>
  <xsl:import href="bigfont.xsl"/>
  <xsl:attribute-set name="note-style">
    <xsl:attribute name="font-style">italic</xsl:attribute>
  </xsl:attribute-set>
</xsl:stylesheet>

xsl:import エレメントを含む1つのスタイルシートの処理中に出現した xsl:stylesheet エレメントは、1つのインポートツリーを形成するような形で扱われる。 インポートツリー内では、各 xsl:stylesheet エレメントが、スタイルシートに含まれる xsl:import エレメントごとに1つの import を子として持つ。 xsl:include エレメントはすべて、インポートツリーの構築以前に解決される。 ある xsl:stylesheet エレメントのインポートツリー内におけるインポートの優先順位は、同一ツリー内で深さ優先の走査で自分よりも後の順位になるような xsl:stylesheet エレメント (つまり、自分の import ツリー上の子よりも後にその xsl:stylesheet が処理される場合) 、より下位に定義される。 各定義と各テンプレートルールのインポートの優先順位は、それらを含む xsl:stylesheet エレメントによって決められる。

以下のような場合を想定する。

この場合、インポートの優先順位は、低い側から DBECA となる。

注: xsl:import エレメントは、すべての定義とテンプレートの手前に現れなくてはならないため、xsl:import エレメントに遭遇した時点でインポートされるスタイルシートを処理する実装は、インポートの優先順位が高まる順に、定義とテンプレートに遭遇することになる。

通常の場合、インポートの優先順位の高い定義やテンプレートルールは、インポートの優先順位の低い定義やテンプレートルールよりも優先される。 詳細は、各種類の定義およびテンプレートルールについてそれぞれ定義されている。

スタイルシートが、自分自身を直接的または間接的にインポートする場合はエラーとなる。 これ以外の場合は、特定の URI を持つスタイルシートが複数の場所にインポートされても特別に扱われない。 インポートツリーは、インポートされた場所ごとに、別々の xsl:stylesheet を持つ。

注: xsl:apply-imports を使用した場合 ([5.6 テンプレートルールのオーバーライド (上書き)] を参照) の動作は、そのスタイルシートが最高のインポートの優先順位を持っている場所だけにインポートされた場合の動作とは異なることがある。

2.7 スタイルシートの埋め込み

通常の場合、XSLT スタイルシートは、ドキュメントエレメントとして xsl:stylesheet エレメントを持つ完全な XML ドキュメントである。 ただし、XSLT スタイルシートを別のリソースに埋め込むこともできる。 スタイルシートの埋め込みには、次の2つの形式がある。

2つ目の形式の埋め込みが容易にできるように xsl:stylesheet エレメントには、ユニークな識別子を示す ID 型のアトリビュートを指定できる。

注: ここで説明した ID 型のアトリビュートを XPath の id 関数と同時に使用するには、このアトリビュートが ID 型であることが DTD 内で実際に宣言されていなければならない (must)。

以下の例は、ドキュメントに独自のスタイルシートを含むことを可能にするプロセッシングインストラクション xml-stylesheet [XML Stylesheet] の使用方法を示している。 URI リファレンスには、xsl:stylesheet エレメントの位置を特定するフラグメント識別子を備えた参照 URI を使用する。

<!DOCTYPE doc SYSTEM "doc.dtd">
<doc>
<head>
<xsl:stylesheet id="style1"
                version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:import href="doc.xsl"/>
<xsl:template match="id('foo')">
  <fo:block font-weight="bold"><xsl:apply-templates/></fo:block>
</xsl:template>
<xsl:template match="xsl:stylesheet">
  
</xsl:template>
</xsl:stylesheet>
</head>
<body>
<para id="foo">
...
</para>
</body>
</doc>
注: ドキュメントに埋め込まれたスタイルシート、またはそのような埋め込まれたスタイルシート内にインクルードあるいはインポートされる可能性があるスタイルシートには、通常、xsl:stylesheet エレメントを無視するようなテンプレートルールを含める必要がある。

3 データモデル

XSLT で使用するデータモデルには、XPath で使用するデータモデルの他に、この章で解説するデータモデルもある。 XSLT は、同一のデータモデルを使用するソースドキュメント、結果ドキュメント、およびスタイルシートドキュメント上で処理を行う。 同一のツリーを持つ2つの XML ドキュメントであれば、XSLT は同様に扱う。

スタイルシート内のプロセッシングインストラクションとコメントは無視される。 つまり、スタイルシートを表現するツリー内にプロセッシングインストラクションノードとコメントノードのどちらも持たないかのように、そのスタイルシートを扱うのである。

3.1 ルートノードの子

ルートノードの子に関する通常時の制約は、結果ツリーに対して緩和される。 結果ツリーでは、エレメントノードが子として持ちうるノードであれば、任意の順序で子ノードを持つことができる。 特に、結果ツリーはテキストノードの子や、任意の数のエレメントノードの子を持ってもよい。 XML 出力メソッド ([16 出力] を参照) を使って書き出された場合、結果ツリーがウェルフォームド XML ドキュメントにならない可能性もある。その場合でも結果ツリーは、常にウェルフォームドな外部一般パース対象エンティティではある。

ソースツリーがウェルフォームド XML ドキュメントをパースして生成された場合、このソースツリーのルートノードは、テキストノードの子は持たず、エレメントの子を1つだけ持つという通常時の制約を自動的に満たす。 DOM を使用するなど、他の方法でソースツリーを生成する場合には、結果ツリーの場合と同様に、ソースツリーに対しても通常時の制約が緩和される。

3.2 ベース URI

各ノードもベース URI と呼ばれる関連付けられた URI を持つ。ベース URI は、相対 URI を表すアトリビュート値を絶対 URI に解決するために使用される。 エレメントまたはプロセッシングインストラクションが外部エンティティに現れる場合、そのエレメントやプロセッシングインストラクションのベース URI は、その外部エンティティの URI である。その他の場合には、ベース URI は、ドキュメントのベース URI である。 ドキュメントノードのベース URI は、ドキュメントエンティティの URI である。 テキストノード、コメントノード、アトリビュートノード、またはネームスペースノードのベース URI になるのは、各ノードの親のベース URIである。

3.3 パース対象外エンティティ

ルートノードは、ドキュメントの DTD で宣言されたパース対象外エンティティそれぞれに URI を提供するマッピング情報を持っている。 URI はエンティティ宣言内で指定されたシステム識別子および公開識別子 (public identifier) から生成される。 XSLT プロセッサはシステム識別子で指定された URI の代わりに、公開識別子を使用してエンティティの URI を生成することもできる。 XSLT プロセッサは、URI 生成に公開識別子を使用しない場合、システム識別子を使用しなければならない (must)。システム識別子が相対 URI である場合、エンティティ宣言を含むリソースの URI をベース URI として使い、相対 URI を絶対 URI に解決しなければならない (must)[RFC2396]

3.4 空白の削除

ソースドキュメントやスタイルシートドキュメントのツリーが構築された後、XSLT が他の処理を行う前に、一部のテキストノードが削除される。 テキストノードが空白文字だけを含む場合を除けば、テキストノードは削除されない。 テキストノードを削除すると、ツリーからそのテキストノードが削除される。 削除処理は、空白を保存しなくてはならない (must) エレメント名の集合を、入力として取る。 削除処理は、スタイルシートとソースドキュメントの両方に適用されるが、空白を保存すべきエレメント名の集合は、スタイルシートとソースドキュメントのそれぞれについて決定される。

下記のいずれかに該当するテキストノードは保存される。

これらの場合以外は、テキストノードを削除する。

xml:space アトリビュートは、ツリーから削除されない。

注: これは、xml:space アトリビュートがリテラル結果エレメントに指定されている場合には、結果に含まれることを意味する。

スタイルシートでは、空白を保存すべきエレメント名の集合を構成するのは、xsl:text だけである。


<xsl:strip-space
  elements = tokens />


<xsl:preserve-space
  elements = tokens />

ソースドキュメントでは、空白を保存すべきエレメント名の集合を、トップレベルエレメントである xsl:strip-spacexsl:preserve-space によって定義する。これらのエレメントはそれぞれ、空白で区切られた NameTest のリストを値に取る elements アトリビュートを持つ。 最初の段階では、空白を保存すべきエレメント名の集合には、すべてのエレメント名が含まれる。 xsl:strip-space エレメント内の NameTest とマッチしたエレメント名は、空白を保存すべきエレメント名の集合から削除される。 xsl:preserve-space エレメント内の NameTest とマッチしたエレメント名は、空白を保存すべきエレメント名の集合に追加される。 あるエレメントが NameTest にマッチするのは、そのエレメントに対して NameTestXPath のノードテストとして真となる場合だけである。 xsl:strip-space エレメントと xsl:preserve-space エレメントとの間でマッチした内容が競合する場合、テンプレートルール競合時と同じ方法で解決する ([5.5 テンプレートルール競合時の解決] を参照)。 従って、特定のエレメント名に対して有効なマッチング結果を以下のように判定する。

上記の判定後にも複数のマッチング結果が残る場合はエラーである。XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、判定後に残ったマッチング結果からスタイルシートの最後方に現れるものを選択し、エラーから回復しなければならない (must)。

4 式

XSLT は、XPath [XPath] で定義する式言語を使用する。XSLT では、以下の例を含め、さまざまな用途に式を使用する。

は、XPath の プロダクション Expr にマッチしなければならない (must)。

式は XSLT で定義するエレメントに関する特定のアトリビュート値として、アトリビュート値テンプレート内に中括弧 ({}) で囲んで記述される。

XSLT では、最も外側の式 (つまり、他の式の一部でない式) は、以下のようにコンテキストを取得する。

5 テンプレートルール

5.1 処理モデル

ソースノードのリストを処理すると、結果ツリーフラグメントが生成される。 結果ツリーは、ルートノードだけを含むリストを処理することによって構築される。 ソースノードのリストは、リスト内の各メンバを順に処理して生成された結果ツリーの構造を追加する形で処理されていく。 ノードの処理は、そのノードにマッチするパターンを持つテンプレートルールをすべて見つけ、その中から最適なテンプレートルールを選択することによって行われる。次に、選択したルールのテンプレートを、カレントノードとなっているノード、およびカレントノードリストとなっているソースノードのリストを使ってインスタンス化する。 テンプレートは通常、次に処理するソースノードのリストを選択するための命令を含んでいる。 このようなマッチング、インスタンス化、選択という処理行程は、処理対象に選ばれる新しいソースノードがなくなるまで続けられる。

この処理モデルを用いて処理した場合と同じ結果が得られるならば、実装はどのようにソースドキュメントを処理してもよい。

5.2 パターン

テンプレートルールは、パターンを使用して適用先のノードを識別する。 パターンは、テンプレートルール内で使用されるとともに、番号付け ([7.7 番号付け] を参照) とキーの宣言 ([12.2 キー] を参照) を行う際にも使用される。 パターンはノードに関する条件の集合を指定する。条件を満たすノードがそのパターンにマッチするノードであり、条件を満たさないノードがそのパターンにマッチしないノードとなる。 パターンのシンタックスは、式のシンタックスのサブセットである。 特に、一定の制約を満たすロケーションパスは、パターンとしても使用できる。 パターンとして使用可能な式は、評価されると常にノード集合型 (node-set) オブジェクトになる。 ノードがパターンにマッチするのは、パターンを式として使い、いくつかの候補になるコンテキストを評価した結果に、そのノードをメンバとして含む場合である。候補になるコンテキストとは、コンテキストノードが、照合対象となっているノードかその祖先ノードの1つであるようなコンテキストである。

以下にパターンの例を示す。

パターンは、Pattern の文法に適合しなければならない (must)。Pattern は、| で区切られたロケーションパスのパターンの集合である。 ロケーションパスのパターンとは、すべてのステップで child 基準点または attribute 基準点のみを使用するロケーションパスである。 パターンでは、descendant-or-self 基準点を使用してはならない (must) が、演算子 / と同様に演算子 // を使用してもよい。 ロケーションパスのパターンを、リテラルな引数を取る id 関数や key 関数の呼び出しで始めることができる。 パターンの述語には、ロケーションパスで述語を使う場合と同様に、任意の式を使用できる。

パターン
[1]   Pattern   ::=   LocationPathPattern
| Pattern '|' LocationPathPattern
[2]   LocationPathPattern   ::=   '/' RelativePathPattern?
| IdKeyPattern (('/' | '//') RelativePathPattern)?
| '//'? RelativePathPattern
[3]   IdKeyPattern   ::=   'id' '(' Literal ')'
| 'key' '(' Literal ',' Literal ')'
[4]   RelativePathPattern   ::=   StepPattern
| RelativePathPattern '/' StepPattern
| RelativePathPattern '//' StepPattern
[5]   StepPattern   ::=    ChildOrAttributeAxisSpecifier NodeTest Predicate*
[6]   ChildOrAttributeAxisSpecifier   ::=   AbbreviatedAxisSpecifier
| ('child' | 'attribute') '::'

パターンの定義がノードにマッチするのは、そのコンテキストについてパターンを式として評価したときに、結果として得られるノード集合のメンバにノードを含むような、候補になるコンテキストが存在する場合に限られる。 ノードが照合される際に、候補となるコンテキストとは、照合対象のノードまたはそのノードの祖先であるコンテキストノードと、そのコンテキストノードだけを含むコンテキストノードリストを持つ。

たとえば、p がすべての p エレメントにマッチするのは、どの p の場合にも、 p エレメントの親をコンテキストとして式 p を評価したときに、その結果のノード集合にメンバとして p エレメントを含むからである。

注: 上記の説明は、p エレメントがドキュメントエレメントであっても、文書のルートがドキュメントエレメントの親であるためにあてはまる。

パターンのセマンティクスは式の評価の視点から間接的に指定されるが、パターンの意味は式の評価の視点で考えなくとも直接容易に理解できる。 パターン内の | は、選択肢を示している。 1つ以上の | で区切られた選択肢を持つパターンは、選択肢のいずれかがマッチすると、パターンとしてマッチする。 パターンが、/ または // で区切られた StepPattern (ステップパターン) の連続によって構成されている場合、パターンの照合は右から左に向かって行われる。 パターンがマッチするのは、右端の StepPattern がマッチし、残りのパターンにも適切なエレメントがマッチする場合だけである。区切り記号が / であれば、親だけが適切なエレメントである。区切り記号が // であれば、すべての祖先が適切なエレメントとなる。 child 基準点を使用する StepPattern は、ノードに対する NodeTest が真であり、そのノードがアトリビュートノードでない場合にマッチする。 attribute 基準点を使用する StepPattern は、ノードに対する NodeTest が真であり、そのノードがアトリビュートノードならばマッチする。 [] が記述されている場合には、コンテキストノードとして照合されるノードと、コンテキストノードリストとして NodeTest にマッチするコンテキストノードの兄弟について、StepPattern 内に含まれる最初の PredicateExpr が評価される。ただし、照合されるノードがアトリビュートノードの場合は異なり、照合されるアトリビュートとして同じ親を持ち、NameTest にマッチするすべてのアトリビュートがコンテキストノードリストとなる。

以下に例を示す。

appendix//ulist/item[position()=1]

上記の記述は、以下の条件がすべて真となる場合にのみ、ノードにマッチする。

5.3 テンプレートルールの定義


<xsl:template
  match = pattern
  name = qname
  priority = number
  mode = qname>
  
</xsl:template>

テンプレートルールは、xsl:template エレメントによって指定される。 match アトリビュートは、ソースノードやルールの適用先ノードを識別する Pattern である。 match アトリビュートは、xsl:template エレメントが name アトリビュートを含む場合を除いて必須である ([6 名前付きテンプレート] を参照)。 match アトリビュートの値が VariableReference を含む場合はエラーとなる。 xsl:template エレメントのコンテンツは、テンプレートルールを適用したときにインスタンス化されるテンプレートである。

たとえば、ある XML ドキュメントが以下の記述を持つとする。

This is an <emph>important</emph> point.

以下のテンプレートルールは、上記の emph エレメントにマッチして、font-weight プロパティが bold のフォーマッティングオブジェクト fo:inline-sequence を生成する。

<xsl:template match="emph">
  <fo:inline-sequence font-weight="bold">
    <xsl:apply-templates/>
  </fo:inline-sequence>
</xsl:template>
注: この仕様の記述例では、ネームスペース http://www.w3.org/1999/XSL/Format を示すためにプレフィックス fo: を使用している。これは [XSL] で定義するフォーマッティングオブジェクトのネームスペースである。

次の項で解説しているように、xsl:apply-templates エレメントはソースエレメントの子を再帰的に処理する。

5.4 テンプレートルールの適用


<xsl:apply-templates
  select = node-set-expression
  mode = qname>
  
</xsl:apply-templates>

以下の例では、1つのchapter エレメントに対して1つのブロックを作成し、次に直下の子を処理する。

<xsl:template match="chapter">
  <fo:block>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>

select アトリビュートがない場合、 xsl:apply-templatesインストラクションは、テキストノードを含むカレントノードのすべての子を処理する。ただし、[3.4 空白の削除] で解説しているとおり、削除したテキストノードは処理しない。 あるエレメントについて、空白だけのノードの削除が有効になっていない場合は、エレメントのコンテンツに含まれるすべての空白をテキストとして処理する。従って、position 関数が返すのと同様に、子エレメント間の空白は、ある子エレメントの位置を決定する際にカウントされる。

select アトリビュートを使用すると、すべての子を処理するのではなくて、式で選択したノードだけを処理できる。 select アトリビュートの値は、である。 その式は評価した結果、ノード集合でなくてはならない (must)。 選択したノード集合の処理は、ソート ([10 ソート] を参照) の指定がなければドキュメント順に行われる。 以下の例では、author-group の子であるすべての author を処理している。

<xsl:template match="author-group">
  <fo:inline-sequence>
    <xsl:apply-templates select="author"/>
  </fo:inline-sequence>
</xsl:template>

以下の例では、author-group の子である author のすべての given-nameを処理している。

<xsl:template match="author-group">
  <fo:inline-sequence>
    <xsl:apply-templates select="author/given-name"/>
  </fo:inline-sequence>
</xsl:template>

以下の例では、book エレメントの子孫エレメントであるすべての heading を処理している。

<xsl:template match="book">
  <fo:block>
    <xsl:apply-templates select=".//heading"/>
  </fo:block>
</xsl:template>

また、カレントノードの子孫でないエレメントも処理できる。以下の例では、department エレメントが子エレメント group および子孫エレメント employee を持つと仮定する。従業員の部署を見つけ、次に department の子である group を処理する。

<xsl:template match="employee">
  <fo:block>
    Employee <xsl:apply-templates select="name"/> belongs to group
    <xsl:apply-templates select="ancestor::department/group"/>
  </fo:block>
</xsl:template>

複数の xsl:apply-templates エレメントを1つのテンプレート内で使用すると、再順序付けを簡略化できる。以下の例では、2つの HTML テーブル (table) を作成する。1つ目のテーブルには国内販売高 (domestic sales)、2つ目のテーブルには海外販売高 (foreign sales) のデータを挿入する。

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="sales/domestic"/>
  </table>
  <table>
    <xsl:apply-templates select="sales/foreign"/>
  </table>
</xsl:template>
注: マッチする子孫が2つ存在し、その一方が他方の子孫となっている可能性もある。 この場合も、特別には扱われずに、 両方の子孫とも通常どおり処理される。以下のようなソースドキュメントの例を示す。
<doc><div><div></div></div></doc>
このルールでは、
<xsl:template match="doc">
  <xsl:apply-templates select=".//div"/>
</xsl:template>
は、外側の div エレメントと内側の div エレメントの両方を処理する。
注: 通常、xsl:apply-templates はカレントノードの子孫のノードだけを処理するために、使用される。 このように xsl:apply-templates を使用することにより、終端のない処理ループ (non-terminating processing loop) が発生することはありえない。 ただし、カレントノードの子孫でないエレメントの処理に xsl:apply-templates を使用すると、終端のない処理ループが発生する可能性もある。 以下に例を示す。
<xsl:template match="foo">
  <xsl:apply-templates select="."/>
</xsl:template>
実装側でこのようなループを検知できる場合もあるが、実装が検知できない終端のないループに、スタイルシートが入り込む可能性もある。 これは、サービス上のセキュリティリスクを否定することを示すかもしれない。

5.5 テンプレートルールの競合解決

1つのソースノードが、複数のテンプレートにマッチする場合もある。 使用するテンプレートルールの決定方法を以下に示す。

  1. 最初に、マッチするテンプレートルールのうちインポートの優先順位の最も高いテンプレートルールよりも、優先順位の低いものをすべて候補から外す。

  2. 次に、マッチしたテンプレートルールのうち、優先度の最も高いテンプレートルールよりも、優先度の低いものをすべて候補から外す。 テンプレートルールの優先度は、テンプレートルール上の priority アトリビュートが指定する。 優先度の値は実数 (プラスまたはマイナス) であり、またオプションの先頭に付けるマイナス記号 (-) を持つプロダクション Number にマッチしていなければならない (must)。 デフォルトの優先度は、以下のように計算される。

    上記の基準から、最も頻出するパターン (特定の型と、特定の展開された名前を持つノードをテストするパターン) の優先度は0になる。これよりもテスト範囲が広いパターン (特定の型と、特定のネームスペース URI が指定された展開された名前を持つノードをテストするパターン) の優先度は -0.25 になる。さらにテスト範囲が広いパターン (特定の型を持つノードだけをテストするパターン) の優先度は -0.5 になる。最も頻出するパターンよりも特化したパターンの優先度は 0.5 になる。

この処理の後に、マッチしたテンプレートルールが複数残る場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、マッチしたテンプレートルールの残りの中からスタイルシートの最後方に現れるものを選択して、エラーから回復しなければならない (must)。

5.6 テンプレートルールのオーバーライド (上書き)


<xsl:apply-imports />

インポートしたスタイルシートのテンプレートルールをオーバーライド (上書き) する ([5.5 テンプレートの競合解決]) ために使用するテンプレートルールでは、xsl:apply-imports エレメントを使ってオーバーライドされたテンプレートルールを呼び出すことができる 。

スタイルシート処理中は常に、カレントテンプレートルールが存在する。 マッチするパターンがテンプレートルールを選択すると、ルール内のテンプレートをインスタンス化している間は、そのテンプレートルールがカレントテンプレートルールになる。 xsl:for-each エレメントをインスタンス化すると、xsl:for-each エレメントのコンテンツをインスタンス化している間は、カレントテンプレートルールは null になる。

xsl:apply-imports は、カレントテンプレートルールを含むスタイルシートエレメントにインポートされたテンプレートルールだけを使って、カレントノードを処理する。ノードはカレントテンプレートルールのモードで処理される。 カレントテンプレートルールが null のときに xsl:apply-imports をインスタンス化した場合はエラーとなる。

たとえば、スタイルシート doc.xsl に、example エレメント用のテンプレートルールを含むと仮定する。

<xsl:template match="example">
  <pre><xsl:apply-templates/></pre>
</xsl:template>

別のスタイルシートは、doc.xsl をインポートして example エレメントの扱いを以下のように変更できる。

<xsl:import href="doc.xsl"/>
<xsl:template match="example">
  <div style="border: solid red">
     <xsl:apply-imports/>
  </div>
</xsl:template>

両者を合わせると、example エレメントは以下の形式のエレメントに変換される。

<div style="border: solid red"><pre>...</pre></div>

5.7 モード

モードを使用すると、エレメントを複数回処理し、毎回異なる結果を得ることができる。

xsl:templatexsl:apply-templates の両者とも、オプションとして mode アトリビュートを使用できる。 mode アトリビュートの値は QName であり、QName は [2.4 修飾名] で解説しているように展開される。 xsl:templatematch アトリビュートを持たない場合には、mode アトリビュートを持ってはならない (must)。 xsl:apply-templates エレメントに mode アトリビュートがある場合、このエレメントは mode アトリビュートに同じ値を持つ xsl:template エレメントのテンプレートルールだけに適用される。xsl:apply-templates エレメントに mode アトリビュートがない場合には、このエレメントは mode アトリビュートを持たない xsl:template エレメントのテンプレートルールだけに適用される。

5.8 組み込みテンプレートルール

スタイルシート内の明示的なテンプレートルールの中にマッチするパターンがなくても、再帰的に処理を継続させることを可能とする、組み込みテンプレートルールがある。 このテンプレートルールは、エレメントノードとルートノードの両方に適用できる。 組み込みテンプレートルールと同等の記述を以下に示す。

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

各モードにも、スタイルシート内の明示的なテンプレートルールの中にマッチするパターンがなくても、同一モードでの処理を再帰的に継続できるようにする組み込みテンプレートルールがある。 このテンプレートルールは、エレメントノードとルートノードの両方に適用できる。 モード m 用の組み込みテンプレートルールと同等の記述を以下に示す。

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

テキストノードとアトリビュートノードについても、テキストをコピーする以下のような組み込みテンプレートルールが存在する。

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

プロセッシングインストラクションおよびコメント用の組み込みテンプレートルールは、何も実行しない。

<xsl:template match="processing-instruction()|comment()"/>

また、ネームスペースノード用の組み込みテンプレートルールも、何も実行しない。 ネームスペースノードにマッチしうるパターンは存在しないため、ネームスペースノードが適用するテンプレートルールは組み込みテンプレートルールだけである。

組み込みテンプレートルールは、スタイルシートの前に暗黙的にインポートされたかのように扱われるため、他のすべてのテンプレートルールよりも低いインポートの優先順位を持つ。 従って、スタイルシート作成者は、明示的なテンプレートルールを定義することにより、組み込みテンプレートルールをオーバーライドできる。

6 名前付きテンプレート


<xsl:call-template
  name = qname>
  
</xsl:call-template>

テンプレートは、名前で呼び出すこともできる。name アトリビュートを持つ xsl:template エレメントは、名前付きテンプレートを指定する。 name アトリビュートの値は QName であり、QNameは [2.4 修飾名] で解説しているように展開される。 xsl:template エレメントが name アトリビュートを持つ場合、match アトリビュートを指定してもしなくてもよい。 xsl:call-template エレメントは、名前でテンプレートを呼び出すため、呼び出すテンプレートを識別するための name アトリビュートを持たなければならない。 xsl:call-template は、xsl:apply-templates と異なり、カレントノードやカレントノードリストを変更しない。

xsl:template エレメントの match アトリビュート、mode アトリビュート、および priority アトリビュートは、xsl:call-template エレメントによるテンプレートの呼び出しに影響を与えない。 同様に、xsl:template エレメントの name アトリビュートも、xsl:apply-templates エレメントによるテンプレートの呼び出しに影響を与えない。

スタイルシートに、同じ名前で同じインポートの優先度を持つテンプレートを複数含む場合はエラーである。

7 結果ツリーの生成

この章では、結果ツリーに直接ノードを生成するインストラクションについて解説する。

7.1 エレメントとアトリビュートの生成

7.1.1 リテラル結果エレメント

テンプレート内では、XSLT ネームスペースに属さない拡張エレメント ([14.1 拡張エレメント] を参照) 以外のスタイルシート内のエレメントは、インスタンス化されて同一の展開された名前 (expanded-name) を持つエレメントノードを生成する。 このエレメントのコンテンツはテンプレートであり、そのテンプレートは、生成されたエレメントノードのコンテンツを付与するためにインスタンス化される。 生成されたエレメントノードは、スタイルシートツリー内のエレメントノードに存在する、XSLT ネームスペース内に名前を持つアトリビュート以外の、アトリビュートを持つことになる。

生成されたエレメントノードは、スタイルシートツリー内のエレメントノードに存在するネームスペースノードのコピーも持つことになる。ただしこれは、文字列値が XSLT ネームスペース URI (http://www.w3.org/1999/XSL/Transform) であるすべてのネームスペースノード、拡張ネームスペースとして宣言されたネームスペース URI ([14.1 拡張エレメント] を参照)、または除外するネームスペース (excluded namespace) として指定されたネームスペース URI には該当しない。 ネームスペース URI は、xsl:stylesheet エレメントに exclude-result-prefixes アトリビュートを指定するか、またはリテラル結果エレメントに xsl:exclude-result-prefixes アトリビュートを指定することにより、除外するネームスペースとして指定される。 これら2つのアトリビュート値は、ネームスペースのプレフィックスを空白で区切ったリストである。 各プレフィックスにバインドされたネームスペースは、除外ネームスペースとして指定される。 exclude-result-prefixes アトリビュート、または xsl:exclude-result-prefixes アトリビュートを持つエレメントのプレフィックスにバインドされたネームスペースが存在しない場合は、エラーである。 ネームスペースのプレフィックスのリストに #default を含めることにより、デフォルトのネームスペース (xmlns で宣言されたもの) を除外ネームスペースとして指定してもよい。 あるネームスペースを除外ネームスペースとして指定すると、exclude-result-prefixes または xsl:exclude-result-prefixes アトリビュートを持つエレメントをルートとするスタイルシートのサブツリー (subtree) 内部に有効となる。ある xsl:stylesheet エレメントをルートとするサブツリーには、そのxsl:stylesheet エレメントの子によってインポートされたスタイルシートやインクルードされたスタイルシートは含まれない。

注: スタイルシートが、ソースツリーの位置を指定するためだけにネームスペース宣言を使用する場合、exclude-result-prefixes アトリビュートにプレフィックスを指定すると、結果ツリー内に余分なネームスペース宣言を生成しないようにできる。

リテラル結果エレメントのアトリビュート値は、アトリビュート値テンプレートとして処理される。 このテンプレートには、中括弧 ({}) 内に記述した式を含めることができる。

結果ツリー内のネームスペース URI を指定するために使用するスタイルシートツリー内のネームスペース URI は、リテラルネームスペース URI と呼ばれる。 この URI に該当するものを以下に示す。


<xsl:namespace-alias
  stylesheet-prefix = prefix | "#default"
  result-prefix = prefix | "#default" />

スタイルシートでは、xsl:namespace-alias エレメントを使用し、1つのネームスペース URI を他のネームスペース URI の エイリアス であると宣言できる。 あるリテラルネームスペース URI が、他のネームスペース URI へのエイリアスになることを宣言している場合、結果ツリー内のそのネームスペース URI は、リテラルネームスペース URI そのものではなく、そのリテラルネームスペース URI がエイリアスとして指しているネームスペース URI になる。 xsl:namespace-alias エレメントは、stylesheet-prefix アトリビュートが指定するプレフィックスにバインドされているネームスペース URI が、result-prefix アトリビュートが指定するプレフィックスにバインドされているネームスペース URI へのエイリアスであると宣言する。 従って、stylesheet-prefix アトリビュートは、スタイルシート内に現れるネームスペース URI を指定し、result-prefix アトリビュートが、その指定に対応して結果ツリー内に現れるネームスペース URI を指定することになる。 プレフィックスの代わりに、#default を使ってデフォルトのネームスペース (xmlns で宣言されたもの) を指定してもよい。 1つのネームスペース URI が、複数の異なるネームスペース URI へのエイリアスになることを宣言されると、最高のインポートの優先順位を持つ宣言が使用される。 このような宣言が複数存在する場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、最高のインポートの優先順位を持つ宣言の中からスタイルシートの最後方に現れるものを選択し、エラーから回復しなければならない (must)。

リテラル結果エレメントを、XSLT ネームスペース URI を使用するエレメント、アトリビュート、またはネームスペースノードを生成するために使用する場合、スタイルシートはエイリアスを使用しなければならない (must)。 たとえば、以下のようなスタイルシートは、

<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/">
  <axsl:stylesheet>
    <xsl:apply-templates/>
  </axsl:stylesheet>
</xsl:template>
<xsl:template match="block">
  <axsl:template match="{.}">
     <fo:block><axsl:apply-templates/></fo:block>
  </axsl:template>
</xsl:template>
</xsl:stylesheet>

以下の形式のドキュメントから XSLT スタイルシートを生成する。

<elements>
<block>p</block>
<block>h1</block>
<block>h2</block>
<block>h3</block>
<block>h4</block>
</elements>
注: XSLT ネームスペース URI 以外のネームスペースについても、エイリアスを使用しなければならない場合もある。たとえば、デジタル署名を扱うネームスペースに属するリテラル結果エレメントは、汎用のセキュリティソフトウェアによる XSLT スタイルシートの誤処理を引き起こす可能性がある。ネームスペースのエイリアスを使用することにより、このような誤処理が発生する可能性を回避できる。

7.1.2 xsl:element を用いたエレメントの生成


<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  
</xsl:element>

xsl:element エレメントは、計算処理された名前を使ってエレメントを生成できる。生成されたエレメントの展開された名前は、必須の name アトリビュートとオプションの namespace アトリビュートによって指定される。 xsl:element エレメントのコンテンツは、生成されたエレメントのアトリビュートおよび子を生成するためのテンプレートである。

name アトリビュートは、アトリビュート値テンプレートとして処理される。 アトリビュート値テンプレートをインスタンス化した結果の文字列が、QName でない場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、xsl:element エレメントのインスタンス化の結果が、xsl:element エレメントのコンテンツをインスタンス化して生成される一連のノードになるようにすることにより、エラーから回復しなければならない (must)。ただし、この一連のノードは、最初にある (単数または複数の) アトリビュートノードを含まない。 namespace アトリビュートが存在しない場合、QName は、xsl:element エレメントに対して有効なネームスペース宣言 (デフォルトのネームスペース宣言でもよい) を使用して、展開された名前に展開される。

また、namespace アトリビュートが存在する場合も、アトリビュート値テンプレートとして処理される。 アトリビュート値テンプレートをインスタンス化した結果の文字列は、URI リファレンスであるべきである。 文字列がシンタックス上正しくない URI リファレンスとなっても、エラーではない。 文字列が空であった場合、エレメントの展開された名前は null のネームスペース URI を持つ。 その他の場合、文字列は生成されたエレメントの展開された名前のネームスペース URI として使用される。 name アトリビュートが指定した QName のローカルパートは、生成されるエレメントの展開された名前のローカルパートとして使用される。

XSLT プロセッサは、生成されたエレメントを XML として出力するためのプレフィックスを選択する際に、name アトリビュートに指定した QName のプレフィックスを使用してもよい。ただし、これは必須ではない。

7.1.3 xsl:attribute を用いたアトリビュートの生成


<xsl:attribute
  name = { qname }
  namespace = { uri-reference }>
  
</xsl:attribute>

xsl:attribute エレメントを使用すると、スタイルシートのリテラル結果エレメントまたは xsl:element などのインストラクションによって生成される結果エレメントに、アトリビュートを追加できる。生成されるアトリビュートの展開された名前は、必須の name アトリビュートおよびオプションの namespace アトリビュートによって指定される。 xsl:attribute エレメントをインスタンス化すると、所属する結果エレメントノードにアトリビュートノードが追加される。 xsl:attribute エレメントのコンテンツは、生成されたアトリビュートの値のためのテンプレートである。

name アトリビュートは、アトリビュート値テンプレートとして処理される。 アトリビュート値テンプレートをインスタンス化した結果の文字列が、QName でない場合、または文字列 xmlns になる場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、結果ツリーにアトリビュートを追加しないことにより、エラーから回復しなければならない (must)。 namespace アトリビュートが存在しない場合、QNamexsl:attribute エレメントに対して有効なネームスペース宣言 (デフォルトのネームスペース宣言を除く) を使用して、展開された名前に展開される。

また、namespace アトリビュートが存在する場合も、アトリビュート値テンプレートとして処理される。 これをインスタンス化した結果の文字列は、URI リファレンスであるべきである。 この文字列がシンタックス上正しくない URI リファレンスとなっても、エラーではない。 文字列が空であった場合、アトリビュートの展開された名前は null のネームスペース URI を持つ。 その他の場合、文字列は生成されるアトリビュートの展開された名前のネームスペース URI として使用される。 name アトリビュートが指定した QName のローカルパートは、生成されるアトリビュートの展開された名前のローカルパートとして使用される。

XSLT プロセッサは、生成したアトリビュートを XML として出力するためのプレフィックスを選択する際に、name アトリビュートに指定した QName のプレフィックスを使用してもよい。ただし、これは必須ではなく、プレフィックスが xmlns の場合には使用してはならない (must)。 以下の例は、実行してもエラーではないが、ネームスペース宣言は出力されない。

<xsl:attribute name="xmlns:xsl" namespace="whatever">http://www.w3.org/1999/XSL/Transform</xsl:attribute>

エレメントにアトリビュートを追加すると、そのエレメントの既存の同一の展開された名前を持つアトリビュートを、置き換えることができる。

以下の場合は、すべてエラーである。

注: xsl:attribute が改行 (newline) 付きのテキストノードを含む場合には、XML の出力にキャラクターリファレンスを含まなければならない (must)。 以下に例を示す。
<xsl:attribute name="a">x
y</xsl:attribute>
この記述から以下の出力が得られる
a="x&#xA;y"
(または同等のキャラクターリファレンス)。 XML の出力は、以下の形にはなりえない。
a="x
y"
これは、XML 1.0 では、アトリビュート値が含む改行文字はスペースに正規化するが、改行文字を表すキャラクターリファレンスは正規化しないと規定しているためである。 データモデル内のアトリビュート値は、正規化した後のアトリビュート値を表している。 ツリー内のアトリビュート値に現れた改行が、キャラクターリファレンスとしてではなく、改行文字として出力された場合、XML を再びパースして生成されたツリー内のアトリビュート値には、改行ではなく1個のスペースを含むことになる。つまり、ツリーが正しく出力されなかったことになる。

7.1.4 名前付きアトリビュートの集合


<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
  
</xsl:attribute-set>

xsl:attribute-set エレメントは、名前が付けられたアトリビュートの集合を定義する。 name アトリビュートでは、アトリビュートの集合の名前を指定する。 name アトリビュートの値は QName であり、QNameは [2.4 修飾名] で解説しているように展開される。 xsl:attribute-set エレメントのコンテンツは、集合内のアトリビュートを指定する0個以上の xsl:attribute エレメントから構成される。

アトリビュートの集合を使用するには、xsl:element エレメント、xsl:copy エレメント [7.5 コピー] を参照)、または xsl:attribute-set エレメントの use-attribute-sets アトリビュートを指定すればよい。 use-attribute-sets アトリビュートの値は、空白で区切られたアトリビュートの集合の名前からなるリストである。 名前はそれぞれ QName として指定され、QName は [2.4 修飾名] で解説しているように展開される。 use-attribute-sets アトリビュートの指定は、名前付きアトリビュート値の集合が含む各アトリビュートに対応する xsl:attribute エレメントを、 use-attribute-sets アトリビュートを持つエレメントのコンテンツの先頭に追加することと同じである。追加の順序は、use-attribute-sets アトリビュートにおいてアトリビュートの集合の名前を指定する順序と同じである。 xsl:attribute-set エレメントに use-attribute-sets アトリビュートを指定した際に、アトリビュートの集合が直接的または間接的に自分自身を使用する結果になる場合は、エラーである。

リテラル結果エレメントで xsl:use-attribute-sets を指定しても、アトリビュートの集合を使用できる。 xsl:use-attribute-sets アトリビュートの値は、空白で区切られたアトリビュートの集合の名前からなるリストである。 xsl:use-attribute-sets アトリビュートは、 xsl:elementuse-attribute-sets アトリビュートを使用する場合と同じ効果を持ち、かつ以下のような追加ルールを持つ。このルールでは、リテラル結果エレメント自体に指定されているアトリビュートは、 実際の xsl:attribute エレメントの手前かつ xsl:use-attribute-sets アトリビュートによって暗黙的に指定された xsl:attribute エレメントの後の位置に、xsl:attribute エレメントによって指定されたかのように扱われる。 従って、リテラル結果エレメントについては、最初に、xsl:use-attribute-sets アトリビュートで名前が付けられたアトリビュートの集合に含まれるアトリビュートが、アトリビュート内にリストされている順序で追加される。次に、リテラル結果エレメントで指定されているアトリビュートが追加される。最後に、xsl:attribute エレメントで指定されているエレメントが追加される。 エレメントにアトリビュートを追加すると、追加先エレメントに存在する同じ名前を持つ既存のアトリビュートが置き換わるため、アトリビュートの集合で指定されているアトリビュートを、リテラル結果エレメント自体で指定されているアトリビュートによってオーバーライドできる。

xsl:attribute-set エレメントに含まれる各 xsl:attribute エレメント内部のテンプレートは、アトリビュートの集合を使用するごとにインスタンス化される。このインスタンス化では、use-attribute-sets アトリビュートまたは xsl:use-attribute-sets アトリビュートを持つエレメントのインスタンス化で使用するものと同一のカレントノードとカレントノードリストを使用する。ただし、どの変数のバインディングを参照できるかを決めるのは、xsl:attribute エレメントのスタイルシート内での位置であって、use-attribute-sets アトリビュートまたは xsl:use-attribute-sets アトリビュートを持つエレメントの位置ではない ([11 変数とパラメータ] を参照) 。従って、参照可能なのは、トップレベルxsl:variable エレメントと xsl:param エレメントが宣言した変数とパラメータだけである。

以下の例では、title-style という名前付きアトリビュートの集合を生成し、テンプレートルール内で使用している。

<xsl:template match="chapter/heading">
  <fo:block quadding="start" xsl:use-attribute-sets="title-style">
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>
<xsl:attribute-set name="title-style">
  <xsl:attribute name="font-size">12pt</xsl:attribute>
  <xsl:attribute name="font-weight">bold</xsl:attribute>
</xsl:attribute-set>

同一の展開された名前を持つアトリビュートの集合に複数の定義が存在すると、それらの定義はマージされる。より高いインポートの優先順位を持つ定義のアトリビュートが、より低いインポートの優先順位を持つ定義のアトリビュートよりも優先される。 同じ展開された名前とインポートの優先順位を持つアトリビュートの集合が2つ存在し、それらが同じアトリビュートを含む場合、よりインポートの優先順位が高く、同じアトリビュートを持つ定義が存在しなければ、エラーである。 XSLT プロセッサは、エラーを通知してもよい。 エラーを通知しない場合には、最高のインポートの優先順位を持つアトリビュートを指定する定義から、スタイルシートの最後方の定義を選択することにより、エラーから回復しなければならない (must)。 アトリビュートの集合内でアトリビュートを定義する場所は、アトリビュートを集合にマージする際にのみ考慮される。アトリビュートの集合を使用するときには区別されない。

7.2 テキストの生成

テンプレートには、テキストノードも含めることができる。[3.4 空白の削除] で解説しているように空白を削除した後にテンプレート内に残った各テキストノードは、結果ツリー内に同一の文字列を持つテキストノードを生成する。 結果ツリー内の隣接するテキストノードは、自動的にマージされる。

テキストはツリーレベルで処理されることに注意しなければならない。従って、テンプレート内のマークアップ &lt; は、スタイルシートツリー内では、文字 < を含むテキストノードに変わる。 次にこの文字は、結果ツリー内に文字 < を含むテキストノードを生成する。さらに、結果ツリーを XML ドキュメントとして外部に出力すると ([16.4 出力エスケープの無効化] で解説しているように出力エスケープが無効化されていなければ)、マークアップ &lt; (または同等のキャラクターリファレンス) に変わる。


<xsl:text
  disable-output-escaping = "yes" | "no">
  
</xsl:text>

リテラルなデータ文字も、xsl:text エレメントでラッピングできる。このラッピングは、削除される空白文字の種類を変更する可能性があるが ([3.4 空白の削除] を参照)、その後の XSLT プロセッサによる記号の扱い方には影響を与えない。

注: XSLT プロセッサ側では、xml:lang アトリビュートおよび xml:space アトリビュートを特別に扱わない。 特に次の点に注意する。

7.3 プロセッシングインストラクションの生成


<xsl:processing-instruction
  name = { ncname }>
  
</xsl:processing-instruction>

xsl:processing-instruction エレメントをインスタンス化すると、プロセッシングインストラクションノードが生成される。xsl:processing-instruction エレメントのコンテンツは、プロセッシングインストラクションノードの文字列値のテンプレートである。xsl:processing-instruction エレメントは、プロセッシングインストラクションノードの名前を指定するための必須の name アトリビュートを持っている。name アトリビュートの値は、アトリビュート値テンプレートとして処理される。

以下に例を示す。

<xsl:processing-instruction name="xml-stylesheet">href="book.css" type="text/css"</xsl:processing-instruction>

上記の記述は、以下のプロセッシングインストラクションを生成する。


name アトリビュートをインスタンス化した結果の文字列が、NCNamePITarget の両方にならない場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、結果ツリーにプロセッシングインストラクションを追加しないことにより、エラーから回復しなければならない (must)。

注: これは、XML の宣言の出力に、xsl:processing-instruction を使用できないことを意味する。 その代わりに、xsl:output エレメント ([16 出力] を参照) を使用すべきである。

xsl:processing-instruction のコンテンツをインスタンス化した際に、テキストノード以外のノードが生成された場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。 エラーを通知しない場合には、問題のあるノードとそのコンテンツを無視することにより、エラーから回復しなければならない (must)。

xsl:processing-instruction のコンテンツをインスタンス化した結果に、文字列 ?> を含む場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、> の直前にあるすべての ? の後ろにスペースを1個挿入することにより、エラーから回復しなければならない (must)。

7.4 コメントの生成


<xsl:comment>
  
</xsl:comment>

xsl:comment エレメントをインスタンス化すると、結果ツリー内にコメントノードが生成される。xsl:comment エレメントのコンテンツは、コメントノードの文字列値のテンプレートである。

以下に例を示す。

<xsl:comment>This file is automatically generated. Do not edit!</xsl:comment>

上記の記述は、以下のコメントを生成する。

xsl:comment のコンテンツをインスタンス化する際に、テキストノード以外のノードが生成された場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、問題のあるノードとそのコンテンツを無視することにより、エラーから回復しなければならない (must)。

xsl:comment のコンテンツをインスタンス化した結果が、文字列 -- を含むか、または末尾に - がある場合はエラーである。 XSLT プロセッサは、エラーを通知してもよい。エラーを通知しない場合には、別の - の直前にあるすべての - の後ろ、およびコメントの末尾にある - の後ろにスペースを1個挿入することにより、エラーから回復しなければならない (must)。

7.5 コピー


<xsl:copy
  use-attribute-sets = qnames>
  
</xsl:copy>

xsl:copy エレメントを使用すると、カレントノードを容易にコピーできる。xsl:copy エレメントをインスタンス化すると、カレントノードのコピーが生成される。カレントノードのネームスペースノードも自動的にコピーされるが、ノードのアトリビュートと子は自動的にコピーされない。xsl:copy エレメントのコンテンツは、生成されたノードのアトリビュートおよび子のためのテンプレートである。このコンテンツは、アトリビュートまたは子を持つことができるノード型 (つまり、ルートノードとエレメントノード) に限ってインスタンス化される。

xsl:copy エレメントは、use-attribute-sets アトリビュート ([7.1.4 名前付きアトリビュートの集合] を参照) を持ってもよい。 このアトリビュートは、エレメントノードをコピーする際にのみ使用される。

ルートノードは、結果ツリーのルートノードを暗黙的に生成するために特別に扱われる。 カレントノードがルートノードである場合、xsl:copy はルートノードを生成せず、そのコンテンツのテンプレートだけを使用する。

たとえば、自分自身の変換は、xsl:copy を用いて以下のように記述できる。

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

カレントノードがアトリビュートの場合に、カレントノードと同じ名前のアトリビュートを生成するために xsl:attribute を使用するとエラーになるような場合には、xsl:copy を使用することもエラーである ([7.1.3 xsl:attribute を用いたアトリビュートの生成] を参照)。

以下の例は、ソースツリーから結果ツリーへの xml:lang アトリビュートのコピーがいかに容易であるかを示している。 スタイルシートに、以下の名前付きテンプレートを定義しているとする。

<xsl:template name="apply-templates-copy-lang">
 <xsl:for-each select="@xml:lang">
   <xsl:copy/>
 </xsl:for-each>
 <xsl:apply-templates/>
</xsl:template>

上記を前提として、xml:lang アトリビュートをコピーする場合、

<xsl:call-template name="apply-templates-copy-lang"/>

上記の記述だけで簡単にコピーができるため、

<xsl:apply-templates/>

上記のエレメントを使用する必要はない。

7.6 テキストの動的生成

テンプレート内では、xsl:value-of エレメントを使用し、計算によりテキストを生成できる。このエレメントは、ソースツリーからのテキストの取り出しや、変数の値の挿入などに使用される。 xsl:value-of エレメントは、select アトリビュートの値として指定したを使ってこの処理を行う。 式は、中括弧 ({}) で囲むことにより、リテラル結果エレメントのアトリビュート値内でも使用できる。

7.6.1 xsl:value-of を用いたテキストの生成


<xsl:value-of
  select = string-expression
  disable-output-escaping = "yes" | "no" />

xsl:value-of エレメントをインスタンス化すると、結果ツリー内にテキストノードが生成される。 必須の select アトリビュートは、である。この式を評価すると、string 関数の呼び出しを実行したかのように、結果のオブジェクトを文字列に変換する。 この文字列は、生成されるテキストノードの文字列値を指定している。 文字列が空の場合、テキストノードは生成されない。生成されたテキストノードは、隣接するすべてのテキストノードとマージされる。

xsl:copy-of エレメントを使用すると、ノード集合を文字列に変換することなく、結果ツリーにコピーできる。 [11.3 xsl:copy-ofを用いた変数とパラメータの値の使用 ] を参照のこと。

以下に、given-name アトリビュートと family-name アトリビュートを持つ person エレメントから HTML の段落を生成する例を示す。 この段落には、カレントノードの given-name アトリビュートの値、1個のスペース、およびカレントノードの family-name アトリビュートの値を、この順序で挿入することになる。

<xsl:template match="person">
  <p>
   <xsl:value-of select="@given-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="@family-name"/>
  </p>
</xsl:template>

もう1つの例として、子エレメント given-name と子エレメント family-name を持つ person エレメントから、HTML の段落を生成している記述を以下に示す。この段落には、カレントノードの子の given-name エレメントの中で最初のものの文字列値とそれに続く1個のスペース、およびカレントノードの子の family-name エレメントの中で最初のものの文字列値を、この順序で挿入することになる。

<xsl:template match="person">
  <p>
   <xsl:value-of select="given-name"/>
   <xsl:text> </xsl:text>
   <xsl:value-of select="family-name"/>
  </p>
</xsl:template>

以下の記述では、各 procedure エレメントの処理を、手順のセキュリティレベルを含む段落から始めている。ある手順に適用されるセキュリティレベルは、procedure エレメントまたはその祖先エレメントの security アトリビュートによって決まる。 また、security アトリビュートを持つエレメントが複数存在する場合、セキュリティレベルは procedure エレメントに最も近いエレメントによって決まる。

<xsl:template match="procedure">
  <fo:block>
    <xsl:value-of select="ancestor-or-self::*[@security][1]/@security"/>
  </fo:block>
  <xsl:apply-templates/>
</xsl:template>

7.6.2 アトリビュート値テンプレート

リテラル結果エレメントのアトリビュートなど、アトリビュート値テンプレートとして処理されるアトリビュート値では、中括弧 ({}) で囲むことによってを使用できる。 アトリビュート値テンプレートは、式とそれを囲む中括弧を式の評価結果で置き換え、結果のオブジェクトを、string 関数の呼び出しを実行したかのように、文字列に変換することによって、インスタンス化される。 アトリビュートをアトリビュート値テンプレートとして処理するように明示された場合を除いて、中括弧は XSLT スタイルシートのアトリビュート値内では認識されない。エレメントのシンタックス要約では、このようなアトリビュート値は中括弧で囲まれている。

注: すべてのアトリビュートを、アトリビュート値テンプレートとして処理するわけではない。 値が式またはパターンのアトリビュート、トップレベルエレメントのアトリビュート、および名前が付けられた XSLT オブジェクトを参照するアトリビュートは、アトリビュート値テンプレートとして処理されない。 さらに xmlns アトリビュートも、アトリビュート値テンプレートとして処理されない。このような処理は、XML ネームスペース勧告 (XML Namespaces Recommendation) に適合しないからである。

以下の例では、img 結果エレメントを、ソース内の photograph エレメントから生成している。img エレメントの src アトリビュートの値は、image-dir 変数の値と、photograph エレメントの子である href の文字列値から算出される。img エレメントの width アトリビュートの値は、photograph エレメントの子である sizewidth アトリビュートの値から算出される。

<xsl:variable name="image-dir">/images</xsl:variable>
<xsl:template match="photograph">
<img src="{$image-dir}/{href}" width="{size/@width}"/>
</xsl:template>

以下のソースを使用する場合、

<photograph>
  <href>headquarters.jpg</href>
  <size width="300"/>
</photograph>

結果は次のようになる。

<img src="/images/headquarters.jpg" width="300"/>

アトリビュート値テンプレートをインスタンス化する際に、式の外側にある右向きまたは左向きの2重中括弧は、1重の中括弧に置き換えられる。 式の外側のアトリビュート値テンプレートでは、右向き中括弧の後ろに2つ目の右向き中括弧がない場合はエラーである。 式の Literal 内にある1重の右向き中括弧が、式を終了する中括弧とは認識されない。

中括弧は、式の内部で再帰的に認識されない。以下に例を示す。

<a href="#{id({@ref})/title}">

この記述は認められない。そのかわりに、より簡単な以下の記述を使用する。

<a href="#{id(@ref)/title}">

7.7 番号付け


<xsl:number
  level = "single" | "multiple" | "any"
  count = pattern
  from = pattern
  value = number-expression
  format = { string }
  lang = { nmtoken }
  letter-value = { "alphabetic" | "traditional" }
  grouping-separator = { char }
  grouping-size = { number } />

xsl:number エレメントは、結果ツリー内にフォーマットした数値を挿入するために使用される。挿入する数値は、式を使って指定してもよい。value アトリビュートは、を含む。この式が評価されると、結果のオブジェクトは number 関数の呼び出しを実行したかのように数値に変換される。 この数値を整数に丸めた後、[7.7.1 数値から文字列への変換アトリビュート] で解説しているアトリビュートを使用して文字列に変換する。この処理では、これらのアトリビュート値をそれぞれアトリビュート値テンプレートとして処理する。 変換が終わると、結果の文字列を結果ツリーに挿入する。 以下の例では、ソートされたリストに番号付けを行っている。

<xsl:template match="items">
  <xsl:for-each select="item">
    <xsl:sort select="."/>
    <p>
      <xsl:number value="position()" format="1. "/>
      <xsl:value-of select="."/>
    </p>
  </xsl:for-each>
</xsl:template>

value アトリビュートを指定していない場合、xsl:number エレメントはソースツリー内のカレントノードの位置に基づいて数値を挿入する。以下のアトリビュートは、カレントノードの番号付けの方法を制御する。

さらに、数値から文字列への変換には、[7.7.1 数値から文字列への変換アトリビュート] で解説しているアトリビュートを使用する。value アトリビュートを指定する場合がこれに該当する。

xsl:number エレメントは、level アトリビュート、count アトリビュート、および from アトリビュートを使って最初に正の整数のリストを構築する。

次に、メンバのリストを [7.7.1 数値から文字列への変換アトリビュート] で解説しているアトリビュートを使って文字列に変換する。この処理の際に、これらのアトリビュート値はそれぞれアトリビュート値テンプレートとして処理される。 変換が終わると、結果の文字列を結果ツリーに挿入する。

以下の例では、ol (ordered list) 内の item に番号付けを行なっている。

<xsl:template match="ol/item">
  <fo:block>
    <xsl:number/><xsl:text>. </xsl:text><xsl:apply-templates/>
  </fo:block>
<xsl:template>

以下の2つのルールは、title エレメントに番号付けを行う。この例は、一連の chapter とその後に続く appendix を含む文書を意図している。これらの chapter および appendix のどちらも section を含み、sectionsubsection を含んでいる。chapter には1、2、3、appendix には A、B、C、chapter 内の section には 1.1、1.2、1.3、appendix 内の section には A.1、A.2、A.3、のように番号付けを行う。

<xsl:template match="title">
  <fo:block>
     <xsl:number level="multiple"
                 count="chapter|section|subsection"
                 format="1.1 "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>
<xsl:template match="appendix//title" priority="1">
  <fo:block>
     <xsl:number level="multiple"
                 count="appendix|section|subsection"
                 format="A.1 "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

以下の例では、chapter 内の note に順次番号付けを行う。

<xsl:template match="note">
  <fo:block>
     <xsl:number level="any" from="chapter" format="(1) "/>
     <xsl:apply-templates/>
  </fo:block>
</xsl:template>

以下の例では、3部分から成るラベルを持つ HTML 内で H4 エレメントの番号付けを行う。

<xsl:template match="H4">
 <fo:block>
   <xsl:number level="any" from="H1" count="H2"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H2" count="H3"/>
   <xsl:text>.</xsl:text>
   <xsl:number level="any" from="H3" count="H4"/>
   <xsl:text> </xsl:text>
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

7.7.1 数値から文字列への変換アトリビュート

以下のアトリビュートは、数値のリストから文字列への変換を制御するために使用される。 数値は0より大きい整数であり、アトリビュートはすべてオプションである。

主要なアトリビュートは、format である。format アトリビュートのデフォルト値は、1である。format アトリビュートは、トークンのシーケンスに分割される。各トークンは、英数文字の最長シーケンスまたは非英数文字の最長シーケンスである。 英数文字とは、Nd、Nl、No、Lu、Ll、Lt、Lm、または Lo の Unicode カテゴリを持つすべての文字を意味する。 英数文字トークン (フォーマットトークン) は、リスト内の各数値で使用するフォーマットを指定する。 最初のトークンが非英数文字のトークンであれば、構築される文字列はそのトークンで始まり、最後のトークンが非英数文字のトークンであれば、構築される文字列はそのトークンで終わることになる。 2つのトークンの間に現れる非英数文字のトークンは、リスト内の数値を結合するためのセパレータトークンである。 n 番目のフォーマットトークンは、リスト内 の n 番目の数値をフォーマットするために使用される。 フォーマットトークンより数値の数が多い場合、最後のフォーマットトークンを使って残りの数値をフォーマットする。 フォーマットトークンが存在しない場合は、フォーマットトークン 1 を使ってすべての数値をフォーマットする。 フォーマットトークンは、数値の 1 を表すために使用する文字列を指定する。2番目以降の各数値は、その数値をフォーマットするために使用するフォーマットトークンの前にあるセパレータトークンによって、手前の数値と区切られる。セパレータトークンが存在しない場合には、.(ピリオド文字) を使用する。

フォーマットトークンは、HTML 4.0 の OL エレメントの type アトリビュートで使用できる値のスーパーセットであり、以下のように変換処理される。

アルファベット順に番号付けを行う際には、lang アトリビュートを使って、どの言語のアルファベットを使用するかを指定する。このアトリビュートは、xml:lang [XML] と同じ範囲の値を取る。lang の値を指定していない場合には、システムの環境から言語を判定するべきである。 実装側は、番号付けをサポートする言語の種類をドキュメントにしておくべきである。

注: 実装側は、特定言語の番号付け動作を仮定せずに、サポートしようとする言語を正確に調べるべきである。 番号付けの規則は、多くの言語において英語の場合と大きく異なっている。

letter-value アトリビュートは、文字を使用する番号付け規則間のあいまいさを排除する。 多くの言語には、文字を使った一般的な番号付け規則が2種類存在する。1つは数値をアルファベット順に文字に割り当てる方法であり、もう1つはその言語で伝統的に使われる別の方法によって数値を各文字に割り当てる。 英語の場合、これらの方法はフォーマットトークン a および i によって指定される番号付け規則に相当する。 いくつかの言語では、各規則の最初の文字が同じために、フォーマットトークンだけではあいまいになる。 値に alphabetic を指定するとアルファベット順が適用され、traditional を指定すると別の規則が適用される。 letter-value アトリビュートを指定しない場合には、どのようにあいまいさを解決するかを実装に依存することになる。

注: 規定に適合する2種類の XSLT プロセッサを使ってある数値を変換した結果が、完全に同じ文字列にならない場合もある。 XSLT プロセッサによっては、いくつかの言語をサポートしないものもある。 xsl:number のアトリビュートによる指定が不可能な特定の言語での、変換を実行する方法には、さらに、バリエーションが存在する可能性がある。 今後のバージョンの XSLT では、このようなバリエーションを制御するためにアトリビュートを追加することを検討している。このため、実装側も実装固有のネームスペースを持つアトリビュートを xsl:number で使用してもよい。

grouping-separator アトリビュートは、十進法の記述内でグループ (たとえば 1000 単位) を分けるための区切り記号を持つ。また、オプションの grouping-size では、グループ化のサイズ (一般に 3 ) を指定できる。 たとえば、grouping-separator="," および grouping-size="3" の場合には、1,000,000 という形式の数値を作るとする。 grouping-separator アトリビュートと grouping-size アトリビュートのどちらか一方しか指定しない場合には、その指定は無視される。

以下に、変換仕様の例を示す。

8 繰り返し


<xsl:for-each
  select = node-set-expression>
  
</xsl:for-each>

結果が規則性のある構造を持つことが分かっている場合には、選択したノードに直接テンプレートを指定できると便利である。 xsl:for-each インストラクションは1つのテンプレートを含む。このテンプレートは、select アトリビュートが指定したによって選択された各ノードに対してインスタンス化される。 select アトリビュートの指定は必須である。 式はノード集合に評価されなければならない (must)。このテンプレートは、選択したノードをカレントノードとして使用し、選択した全ノードのリストをカレントノードリストとして使用してインスタンス化される。ノードは、ソートの指定がなければ ([10 ソート] を参照)、ドキュメント順に処理される。

たとえば、以下の構造を持つ XML ドキュメントを仮定する。

<customers>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
  <customer>
    <name>...</name>
    <order>...</order>
    <order>...</order>
  </customer>
</customers>

以下の記述は、各 customer エレメントの列を持つテーブルを含む HTML 文書を生成する。

<xsl:template match="/">
  <html>
    <head>
      <title>Customers</title>
    </head>
    <body>
      <table>
	<tbody>
	  <xsl:for-each select="customers/customer">
	    <tr>
	      <th>
		<xsl:apply-templates select="name"/>
	      </th>
	      <xsl:for-each select="order">
		<td>
		  <xsl:apply-templates/>
		</td>
	      </xsl:for-each>
	    </tr>
	  </xsl:for-each>
	</tbody>
      </table>
    </body>
  </html>
</xsl:template>

9 条件付き処理

XSLT には、テンプレート内での条件付き処理をサポートする、 xsl:if および xsl:choose の2つのインストラクションがある。 xsl:if インストラクションは、単純な if-then (~に該当すれば~を実行する) 型の条件処理を行い、xsl:choose インストラクションは、選択肢がいくつかある場合の選択処理をサポートする。

9.1 xsl:if を用いた条件付き処理


<xsl:if
  test = boolean-expression>
  
</xsl:if>

xsl:if エレメントは test アトリビュートを持つ。このアトリビュートはを指定する。 エレメントのコンテンツはテンプレートである。式を評価すると、結果のオブジェクトは boolean 関数の呼び出しを実行したかのようにブール型に変換される。 結果が真の場合はコンテンツのテンプレートをインスタンス化し、それ以外の場合は何も生成しない。 以下の例では、namelist に含まれる name をフォーマットし、コンマ区切りのリストにしている。

<xsl:template match="namelist/name">
  <xsl:apply-templates/>
  <xsl:if test="not(position()=last())">, </xsl:if>
</xsl:template>

以下の例では、テーブルの行を1行おきに yellow にしている。

<xsl:template match="item">
  <tr>
    <xsl:if test="position() mod 2 = 0">
       <xsl:attribute name="bgcolor">yellow</xsl:attribute>
    </xsl:if>
    <xsl:apply-templates/>
  </tr>
</xsl:template>

9.2 xsl:choose を用いた条件付き処理


<xsl:choose>
  
</xsl:choose>

<xsl:when
  test = boolean-expression>
  
</xsl:when>

<xsl:otherwise>
  
</xsl:otherwise>

xsl:choose エレメントは、いくつかの選択肢から1つを選択する。このエレメントには、一連の xsl:when エレメントに続いて、オプションの xsl:otherwise エレメントを記述する。各 xsl:when エレメントが持つアトリビュートは、test アトリビュート1つだけである。このアトリビュートは を指定する。xsl:when エレメントと xsl:otherwise エレメントのコンテンツは、テンプレートである。 xsl:choose エレメントを処理する際には、各 xsl:when エレメントを順番にテストする。このテストでは、boolean 関数の呼び出しを実行したかのように、式を評価して結果のオブジェクトをブール型に変換する。テスト結果が真の xsl:when エレメントのうち、最初のエレメントのコンテンツだけをインスタンス化する。 テスト結果が真の xsl:when がない場合は、xsl:otherwise エレメントのコンテンツをインスタンス化する。 テスト結果が真の xsl:when エレメントがなく、xsl:otherwise エレメントが存在しない場合は、何も生成しない。

以下の例では、orderedlist のネスト構造の深さに合わせ、アラビア数字、アルファベット、またはローマ数字を使って番号付けしたリストに itemを列挙している。

<xsl:template match="orderedlist/listitem">
  <fo:list-item indent-start='2pi'>
    <fo:list-item-label>
      <xsl:variable name="level"
                    select="count(ancestor::orderedlist) mod 3"/>
      <xsl:choose>
        <xsl:when test='$level=1'>
          <xsl:number format="i"/>
        </xsl:when>
        <xsl:when test='$level=2'>
          <xsl:number format="a"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:number format="1"/>
        </xsl:otherwise>
      </xsl:choose>
      <xsl:text>. </xsl:text>
    </fo:list-item-label>
    <fo:list-item-body>
      <xsl:apply-templates/>
    </fo:list-item-body>
  </fo:list-item>
</xsl:template>

10 ソート

<xsl:sort
  select = string-expression
  lang = { nmtoken }
  data-type = { "text" | "number" | qname-but-not-ncname }
  order = { "ascending" | "descending" }
  case-order = { "upper-first" | "lower-first" } />

ソートを指定するには、xsl:apply-templates エレメントまたは xsl:for-each エレメントの子に、xsl:sort エレメントを追加する。 ソートキーの指定は、1番目の xsl:sort 子エレメントには1次ソートキーを指定し、2番目の xsl:sort 子エレメントには2次ソートキーを指定するというように行う。 xsl:apply-templates エレメントまたは xsl:for-each エレメントに1つまたは複数の xsl:sort 子エレメントを含む場合、選択したノードをドキュメント順に処理するのではなく、指定したソートキーに従ってソートしてからソート後の順序で処理する。 xsl:sort エレメントを xsl:for-each エレメント内で使用する場合は、xsl:sort エレメントを先頭に記述しなければならない (must)。 テンプレートを xsl:apply-templatesxsl:for-each を使用してインスタンス化すると、カレントノードリストは、処理されるノードがソートした順序に整列した完全なリストになる。

xsl:sort は、を値に取る select アトリビュートを持つ。 各ノードの処理では、カレントノードとして各ノードを使用し、カレントノードリストとしてソートしていない処理対象ノードの完全なリストを使って式を評価する。 結果のオブジェクトは、string 関数の呼び出しを実行したかのように文字列に変換される。この文字列をノードのソートキーとして使用する。 select アトリビュートのデフォルト値は . のため、カレントノードの文字列値をソートキーとして使用することになる。

この文字列が、ノードのソートキーの役割を果たす。xsl:sort で使用する以下のオプションのアトリビュートは、ソートキーのリストをどのようにソートするかを制御する。これらの全アトリビュート値は、アトリビュート値テンプレートとして処理される。

注: 規定に適合する2種類の XSLT プロセッサのソート動作が完全に同じにならない場合もある。 XSLT プロセッサによっては、いくつかの言語をサポートしないものもある。 また、どのような言語にも、xsl:sort のアトリビュートで指定できないソート規則のバリエーションが存在する可能性がある。たとえば日本語の場合には、ひらがなとカタカナの優先順序の問題がある。 今後のバージョンの XSLT では、このようなバリエーションを制御するため、アトリビュートを追加することを検討している。 この問題に関しては、実装側でも実装固有のネームスペースを持つアトリビュートを xsl:sort で使用してもよい。
注: 実装を開発するベンダは、多言語対応のソート処理に関する情報について [UNICODE TR10] を調査することを推奨される。

ソートは安定していなくてはならない (must)。ソート後のノードリストでは、同じ値のソートキーを持つサブリストはすべて、ドキュメント順になっていなければならない (must)。

たとえば、以下のような employee データベースのフォームを仮定する。

<employees>
  <employee>
    <name>
      <given>James</given>
      <family>Clark</family>
    </name>
    ...
  </employee>
</employees>

この場合、従業員の name でソートしたリストは、以下のように生成できる。

<xsl:template match="employees">
  <ul>
    <xsl:apply-templates select="employee">
      <xsl:sort select="name/family"/>
      <xsl:sort select="name/given"/>
    </xsl:apply-templates>
  </ul>
</xsl:template>
<xsl:template match="employee">
  <li>
    <xsl:value-of select="name/given"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="name/family"/>
  </li>
</xsl:template>

11 変数とパラメータ



<xsl:variable
  name = qname
  select = expression>
  
</xsl:variable>


<xsl:param
  name = qname
  select = expression>
  
</xsl:param>

変数とは、ある値にバインドすることのできる名前である。変数のバインド先の値 (変数の) は、式が返すことのできる型であれば、どの型のオブジェクトでもよい。変数のバインドに使用できるエレメントには、xsl:variablexsl:param の2つがある。xsl:param 変数に指定される値は、バインディングのデフォルト値に限るという点が両者の違いである。内部に xsl:param エレメントが現れるテンプレートまたはスタイルシートを呼び出すと、デフォルト値の代わりに使用するパラメータを渡すこともできる。

xsl:variablexsl:param のどちらも、name アトリビュートは必須である。このアトリビュートは変数の名前を指定する。 name アトリビュートの値は QName であり、この値は [2.4 修飾名] で解説しているように展開される。

これらの変数バインドエレメント (Variable-binding element) を使用する場合、あるバインディングを参照できるスタイルシートツリーの範囲は限定される。この範囲内では、変数バインドエレメント自身から参照可能な変数のバインディングはすべて隠蔽される。 そのため、もっとも内側にある変数のバインディングのみが参照可能である。 ある式のスコープに含まれる変数のバインディングの集合は、スタイルシートにその式が現れる時点で参照可能なバインディングである。

11.1 結果ツリーフラグメント

変数は式言語に新しいデータ型を導入する。 この新しいデータ型を、結果ツリーフラグメントと呼ぶ。 変数は4つの基本的な XPath のデータ型 (string、number、boolean、node-set) のいずれかにバインドするのではなくて、結果ツリーフラグメントにバインドしてもよい。 結果ツリーフラグメントは、結果ツリーの断片 (フラグメント) を表す。 結果ツリーフラグメントは、ルートノードを1つだけ含むノード集合と同様に扱われる。 ただし、結果ツリーフラグメントに対して許される演算は、ノード集合に対して許されている演算のサブセットである。 文字列に対して許される演算だけが、結果ツリーフラグメントでも許される (文字列に対する演算では、最初に、文字列を数値またはブール型に変換する処理を含むことができる)。 特に異なるのは、結果ツリーフラグメントでは演算子 ///、および [] を使用できないことである。 許可されている演算を結果ツリーフラグメントに対して実行すると、同等のノード集合に対する演算と全く同様に動作する。

結果ツリーフラグメントを結果ツリーにコピーすると ([11.3 xsl:copy-of を用いた変数とパラメータの値の使用] を参照)、その結果ツリーフラグメントと同等のノード集合内に存在するルートノードのすべての子ノードが、連続して結果ツリーに追加される。

式は、結果ツリーフラグメント型の変数を参照する方法、結果ツリーフラグメントを返す拡張関数を呼び出す方法、または値が結果ツリーフラグメントのシステムプロパティを取得する方法のいずれかによってのみ、結果ツリーフラグメント型の値を返すことができる。

11.2 変数とパラメータの値

変数バインドエレメントでは、3つの方法のいずれかで変数の値を指定できる。

注: 位置によってノードを選択するために変数を使用する場合、以下のように記述しないように注意する。
<xsl:variable name="n">2</xsl:variable>
...
<xsl:value-of select="item[$n]"/>
この記述では、最初の item エレメントの値を出力することになる。これは、変数 n が数値ではなく、結果ツリーフラグメントにバインドされるためである。 その代わりに、以下のように記述するとよい。
<xsl:variable name="n" select="2"/>
...
<xsl:value-of select="item[$n]"/>
または
<xsl:variable name="n">2</xsl:variable>
...
<xsl:value-of select="item[position()=$n]"/>
注: 空のノード集合をパラメータのデフォルト値として指定する場合、以下のように行うと便利である。
<xsl:param name="x" select="/.."/>

11.3 xsl:copy-of を用いた変数とパラメータの値の使用


<xsl:copy-of
  select = expression />

xsl:copy-of エレメントを使用すると、結果ツリーフラグメントを結果ツリーに挿入できる。この場合、xsl:value-of を使用する場合のように ([7.6.1 xsl:value-of を用いたテキストの生成] を参照)、最初に文字列に変換する必要はない。必須の select アトリビュートには、が含まれる。 式の評価結果が結果ツリーフラグメントであれば、フラグメント全体を結果ツリー内にコピーする。 結果がノード集合であれば、ノード集合内の全ノードをドキュメント順に結果ツリー内にコピーする。エレメントノードをコピーすると、エレメントノード自体とともにアトリビュートノード、ネームスペースノード、エレメントノードの子もコピーされる。ルートノードは、子をコピーすることによってコピーされる。 結果がノード集合または結果ツリーフラグメントのいずれでもない場合には、xsl:value-of を使用する場合と同様に、その結果を文字列に変換してから結果ツリーに挿入する。

11.4 トップレベルの変数とパラメータ

xsl:variable および xsl:param の両者とも、トップレベルのエレメントとして使用できる。 トップレベルに置く変数バインドエレメントでは、どこからでも参照できるグローバル変数を宣言する。 トップレベルに置く xsl:param エレメントでは、スタイルシートに渡すパラメータを宣言する。XSLTでは、パラメータをスタイルシートに渡すためのメカニズムを定義しない。 1つのスタイルシートに、名前とインポートの優先順位が同じであるトップレベルの変数のバインディングが複数含まれる場合はエラーである。 トップレベルにおいては、変数の値を指定する式またはテンプレートは、ソースドキュメントのルートノードを処理する際に使用されるコンテキストと同じコンテキストで評価される。 カレントノードはソースドキュメントのルートノードであり、カレントノードリストはソースドキュメントのルートノードだけを含むリストである。 あるグローバル変数 x の値を指定するテンプレートまたは式がグローバル変数 y を参照している場合、y の値が x の値より先に計算処理されなければならない (must)。 あらゆるグローバル変数の定義においてこの順序で処理できなければ、エラーである。言いかえれば、定義間に循環関係がある場合はエラーとなる。

以下の例では、グローバル変数 para-font-size を宣言し、アトリビュート値テンプレートで参照している。

<xsl:variable name="para-font-size">12pt</xsl:variable>
<xsl:template match="para">
 <fo:block font-size="{$para-font-size}">
   <xsl:apply-templates/>
 </fo:block>
</xsl:template>

11.5 テンプレート内部の変数とパラメータ

xsl:variablexsl:param は、どちらもトップレベルだけでなく、テンプレート内でも使用できる。 xsl:variable は、インストラクションが使用可能なテンプレート内部であれば、その位置に関わらず使用できる。 この場合、それに続くすべての兄弟と子孫がバインディングを参照できる。 このバインディングは、xsl:variable エレメント自身からは参照できないことに注意する。 xsl:param は、xsl:template エレメントの先頭に子として記述できる。 このような記述であれば、このバインディングはそれに続くすべての兄弟と子孫から参照できる。 ただし、xsl:param エレメント自身からは参照できないことに注意する。

同じ名前を持つ他のバインディングを参照できる位置に新たに現れたバインディングは、以前のバインディングを隠蔽する。 あるテンプレート内部の xsl:variable エレメントまたは xsl:param エレメントが作成したバインディングが、同一テンプレート内の xsl:variable エレメントまたは xsl:param エレメントが作成したバインディングを隠蔽する場合はエラーである。 ただし、テンプレート内部の xsl:variable エレメントまたは xsl:param エレメントが作成したバインディングが、トップレベルxsl:variable エレメントまたは xsl:param エレメントが作成したバインディングを隠蔽する場合はエラーではない。 従って、以下の例はエラーである。

<xsl:template name="foo">
<xsl:param name="x" select="1"/>
<xsl:variable name="x" select="2"/>
</xsl:template>

ただし、以下の例はエラーではない。

<xsl:param name="x" select="1"/>
<xsl:template name="foo">
<xsl:variable name="x" select="2"/>
</xsl:template>
注: Java において、テンプレート内の xsl:variable エレメントと最も似ているのは、初期化子のある final ローカル変数の宣言である。 以下に例を示す。
<xsl:variable name="x" select="'value'"/>
上記の記述は、以下の記述に似たセマンティクスを持つ。
final Object x = "value";
XSLT には、以下に示す Java の代入演算子と同等の記述方法はない。
x = "value";
この理由は、この方法を取り入れると、先頭から終わりまで続くバッチ的な手法以外で、ドキュメントの処理を実装するのが困難になるためである。

11.6 テンプレートへのパラメータの引き渡し

<xsl:with-param
  name = qname
  select = expression>
  
</xsl:with-param>

パラメータは、xsl:with-param エレメントを用いてテンプレートに渡される。必須の name アトリビュートは、パラメータ (バインディングの値が入れ換えられる変数) の名前を指定する。name アトリビュートの値は QName であり、この値は [2.4 修飾名] で解説しているように展開される。 xsl:with-param は、xsl:call-template および xsl:apply-templates のどちらの内部でも使用できる。 このパラメータの値の指定方法は、xsl:variablexsl:param の場合と同じである。 xsl:with-param エレメントで指定された値の計算処理には、このエレメントが現れる xsl:apply-templates エレメントまたは xsl:call-template エレメントの場合と同一のカレントノードとカレントノードリストを使用する。 x を受け取る xsl:param エレメントを持たないテンプレートに、パラメータ x を渡してもエラーにはならない。このようなパラメータは単に無視される。

以下の例では、数値のフォーマットを制御する引数を持つ numbered-block 用の名前付きテンプレートを定義している。

<xsl:template name="numbered-block">
  <xsl:param name="format">1. </xsl:param>
  <fo:block>
    <xsl:number format="{$format}"/>
    <xsl:apply-templates/>
  </fo:block>
</xsl:template>
<xsl:template match="ol//ol/li">
  <xsl:call-template name="numbered-block">
    <xsl:with-param name="format">a. </xsl:with-param>
  </xsl:call-template>
</xsl:template>

12 追加の関数

この章では、XPath のコア関数ライブラリに追加した XSLT 固有の関数について説明する。 これらの追加した関数の一部は、スタイルシートのトップレベルエレメントが指定した情報も利用するため、この章でもそれらのエレメントについて解説する。

12.1 複数のソースドキュメント

関数: node-set document(object, node-set?)

document 関数は、メインのソースドキュメント以外の XML ドキュメントへのアクセスを可能にする。

document 関数が引数を1つだけ持ち、その引数がノード集合である場合の結果は、引数のノード集合に含まれる各ノードについて、ノードの文字列値を1番目の引数にし、そのノードが唯一のメンバであるノード集合を2番目の引数にして document 関数を呼び出し、それらの結果の和集合と等しい。 document 関数が引数を2つ持ち、1番目の引数がノード集合である場合の結果は、引数のノード集合に含まれる各ノードについて、ノードの文字列値を1番目の引数にし、2番目の引数を document 関数に渡す2番目の引数にして document 関数を呼び出し、それらの結果の和集合と等しい。

document 関数に指定した1番目の引数がノード集合でない場合、1番目の引数は string 関数の呼び出しを実行したかのように文字列に変換される。 この文字列は URI リファレンスとして扱われ、次にこの URI が特定したリソースを取得する。 取得動作の結果のデータは XML ドキュメントとしてパースされ、データモデルに従ってツリーを構築する ([3 データモデル] を参照)。 リソースの取得中にエラーが発生した場合、XSLT プロセッサはエラーを通知してもよい。エラーを通知しない場合には、空のノード集合を返すことによってエラーから回復しなければならない (must)。 データ取得エラーの例としては、URI で使われている URI スキーマを XSLT プロセッサがサポートしていない場合が挙げられる。 XSLT プロセッサは、特定の URI スキーマをサポートする必要はない。 ただし、XSLT プロセッサのドキュメントでは、どの URI スキーマをサポートしているかを明示すべきである。

URI リファレンスがフラグメント識別子を含まない場合、ドキュメントのルートノードだけを含むノード集合が返される。 URI リファレンスがフラグメント識別子を含む場合、この関数は URI リファレンスのフラグメント識別子が識別したツリー内のノードを格納したノード集合を返す。 フラグメント識別子のセマンティクスは、URI による取得結果のメディア型によって決まる。 フラグメント識別子の処理過程でエラーが発生した場合、XSLT プロセッサはエラーを通知してもよい。エラーを通知しない場合には、空のノード集合を返すことによってエラーから回復しなければならない (must)。 以下のようなエラーが考えられる。

取得結果のメディア型に関わらず、取得を実行した結果のデータは XML ドキュメントとしてパースされる。トップレベルのメディア型がテキスト (text) の場合は、メディア型が text/xml の場合と同じ方法でパースされる。それ以外の場合は、メディア型が application/xml の場合と同じ方法でパースされる。

注: トップレベルの xml メディア型は存在しないため、text/xml または application/xml 以外のメディア型を持つデータが、実際には XML であることがある。

URI リファレンスが相対 URI の場合もある。2番目の引数のノード集合に含まれるノードのうち、ドキュメント順で最初のノードのベース URI ([3.2 ベース URI] を参照) を、相対 URI を絶対 URI に解決するためのベース URI として使用する。 2番目の引数が省略されている場合には、document 関数の呼び出しを含む式を記述しているスタイルシート内のノードのベース URI をデフォルトとして使用する。 長さがゼロの URI リファレンスは、URI リファレンスを解決する際に基準になる、ドキュメントへの相対的な参照であることに注意しなければならない。従って document("") は、スタイルシートのルートノードを参照することになる。そのスタイルシートのツリー表現は、そのスタイルシートを含む XML ドキュメントが、最初のソースドキュメントであった場合と全く同じになる。

同一の URI が識別した2つのドキュメントは、同一のドキュメントとして扱われる。 識別時の比較に使われる URI は相対 URI 解決後の絶対 URI であり、フラグメント識別子を1つも含まない。 1つのルートノードと別のルートノードが同一のドキュメントからのものである場合には、同一のノードとして扱われる。 従って、以下の式は常に真になる。

generate-id(document("foo.xml"))=generate-id(document("foo.xml"))

document 関数を使用した場合、ノード集合が複数のドキュメントからのノードを含む可能性が高くなる。 このようなノード集合が返されると、同じドキュメントが含んでいる2つのノードの相対的なドキュメント順は、XPath [XPath] が定義する通常のドキュメント順になる。 異なるドキュメントからの2つのノードの相対的なドキュメント順は、その2つのノードを含む実装依存のドキュメントの順序付けに従う。 ドキュメント順の決定方法については、一貫性を持って順序を決めること (must) 以外に制約はない。 つまり1つの実装は、同じ内容のドキュメントの集合については、常に同じ順序付けをしなければならない (must)。

12.2 キー

キーを使用すると、暗黙的な相互参照構造を持つドキュメントを扱うことができる。 XML のアトリビュート型である IDIDREF、および IDREFS は、XML ドキュメントの相互参照を明示的に利用可能にするメカニズムを提供する。 XSLT は XPath の id 関数を使用してこのメカニズムをサポートしている。 ただし、このメカニズムには以下のような多くの制限がある。

このような制限を持つため、XML ドキュメントは、ID、IDREF、IDREFS 型の各アトリビュートで明示的に宣言されていない相互参照構造を含む場合がある。

キーは以下の3つから成る。

  1. キーを持つノード

  2. キーの名前 (展開された名前)

  3. キーの値 (文字列)

スタイルシートは、xsl:key エレメントを用いて各ドキュメントごとにキーの集合を宣言する。 このキーの集合が、ノード x、名前 y、値 z を持つメンバを含むとすると、ノード x には名前 y と値 z を持つキーがある、と表現する。

このようにキーは一般化された ID のため、XML の ID のような制限はない。


<xsl:key
  name = qname
  match = pattern
  use = expression />

キーの宣言には、xsl:key エレメントを使用する。name アトリビュートはキーの名前を指定する。name アトリビュートの値は QName であり、この値は [2.4 修飾名] で解説しているように展開される。 match アトリビュートは1つの Pattern である。xsl:key エレメントは、match アトリビュートに指定されたパターンにマッチするすべてのノードのキーの情報を提供する。 use アトリビュートはキーの値を指定するである。この式はパターンにマッチしたノードごとに1度ずつ評価される。 その結果がノード集合であれば、パターンにマッチするノードは、そのノード集合内のそれぞれのノードについて、ノードの文字列値を値とし指定した名前を持つキーを持つ。それ以外の場合は、結果は文字列に変換され、パターンにマッチするノードは、変換後の文字列そのものを値とし指定した名前を持つキーを持つ。 従って xsl:key エレメントが以下の条件を満たす場合に限り、ノード x に名前 y と値 z を持つキーが存在する。

所定のノードにマッチする xsl:key エレメントが複数存在することもあるので注意しなけばならない。エレメントのインポートの優先順位が異なっていても、マッチしている xsl:key エレメントはすべて使用される。

use アトリビュートまたは match アトリビュートのいずれかの値が VariableReference を含む場合はエラーである。

関数: node-set key(string, object)

key 関数は、ID に対して id 関数が実行する動作をキーに対して実行する。 1番目の引数にはキーの名前を指定する。 この引数の値は QName でなければならない (must)。この値は、[2.4 修飾名] で解説しているように展開される。 key 関数の2番目の引数がノード集合型の引数である場合の結果は、key 関数を引数のノード集合が含む各ノードの文字列のに適用し、それらの結果の和集合である。 key 関数の2番目の引数がその他の型であれば、string 関数の呼び出しを実行したかのように、その引数を文字列に変換する。そして、コンテキストノードと同じドキュメントが含むノードのうち、名前付きキーの値がこの文字列に等しいノードを持つノード集合が返される。

以下に宣言の例を示す。

<xsl:key name="idkey" match="div" use="@id"/>

上の宣言において、式 key("idkey",@ref) が、id(@ref) と同じノード集合を返すためには、まず、XML ソースドキュメントに宣言している唯一の ID 型のアトリビュートが以下のコンテンツであり、

<!ATTLIST div id ID #IMPLIED>

なおかつ、カレントノードの ref アトリビュートは空白を含んではならない。

関数ライブラリを記述するドキュメントにおいて、以下のように prototype エレメントを用いて関数を定義すると仮定し、

<prototype name="key" return-type="node-set">
<arg type="string"/>
<arg type="object"/>
</prototype>

以下のように function エレメントが関数の名前を参照しているとすると、

<function>key</function>

スタイルシートは、以下のようにして参照と定義の間にハイパーリンクを生成できる。

<xsl:key name="func" match="prototype" use="@name"/>
<xsl:template match="function">
<b>
  <a href="#{generate-id(key('func',.))}">
    <xsl:apply-templates/>
  </a>
</b>
</xsl:template>
<xsl:template match="prototype">
<p><a name="{generate-id()}">
<b>Function: </b>
...
</a></p>
</xsl:template>

key 関数は、コンテキストノードを含むドキュメント以外のドキュメントから、キーを取得するために使用できる。 たとえば <bibref>XSLT</bibref> というフォームで書籍目録を参照するドキュメントが存在し、書籍目録のデータベースを含む別の XML ドキュメント bib.xml には、以下のフォームでエントリーを含むと仮定する。

<entry name="XSLT">...</entry>

この場合スタイルシートでは、以下のように bibref エレメントを変換できる。

<xsl:key name="bib" match="entry" use="@name"/>
<xsl:template match="bibref">
  <xsl:variable name="name" select="."/>
  <xsl:for-each select="document('bib.xml')">
    <xsl:apply-templates select="key('bib',$name)"/>
  </xsl:for-each>
</xsl:template>

12.3 数字のフォーマット

関数: string format-number(number, string, string?)

format-number 関数は、2番目の引数として指定されたフォーマットパターン文字列と、3番目の引数として名付けられたデシマルフォーマット (decimal-format) を使用し、1番目の引数を文字列に変換する。3番目の引数を指定していない場合は、デフォルトのデシマルフォーマットを使用する。 フォーマットパターン文字列は、JDK 1.1 の DecimalFormat クラスが規定するシンタックスで表される。 フォーマットパターン文字列は、ローカライズされたノテーションで表される。 デシマルフォーマットは、パターン内で特別な意味を持つ文字を規定する (引用符はローカライズされないので、これには含まない)。 フォーマットパターンには通貨記号 (#x00A4) を含めてはならない (must)。これは、JDK 1.1 の初期リリース版以後に通貨記号をサポートするようになったためである。デシマルフォーマットの名前は QName でなければならない (must)。この値は [2.4 修飾名] で解説しているように展開される。 スタイルシートが、指定された展開された名前を持つデシマルフォーマットの宣言を含まない場合はエラーである。

注: XSLT の実装に JDK 1.1 の実装を使用する必要はなく、また、XSLT を Java で記述する必要もない。
注: スタイルシートは、数字のまるめ方の制御に XPath のその他の機能を使用できる。


<xsl:decimal-format
  name = qname
  decimal-separator = char
  grouping-separator = char
  infinity = string
  minus-sign = char
  NaN = string
  percent = char
  per-mille = char
  zero-digit = char
  digit = char
  pattern-separator = char />

xsl:decimal-format エレメントでは、デシマルフォーマットを宣言して format-number 関数が使用するフォーマットパターンの解釈を制御する。エレメントが name アトリビュートを持つ場合は、このエレメントは名前付きのデシマルフォーマットを宣言する。それ以外の場合には、デフォルトのデシマルフォーマットを宣言する。 name アトリビュートの値は QName であり、この値は [2.4 修飾名] で解説しているように展開される。 デフォルトのデシマルフォーマットまたは任意の名前を持つデシマルフォーマットが、(異なるインポートの優先順位を持っていても) 複数回宣言される場合はエラーである。ただしそれらの宣言において、(あらゆるデフォルト値も含めた) すべてのアトリビュート値が同じ場合はエラーにならない。

xsl:decimal-format で指定するその他のアトリビュートは、JDK 1.1 の DecimalFormatSymbols クラスが提供するメソッドに対応している。 xsl:decimal-format エレメントには、メソッド get および set の各組について1つずつのアトリビュートが定義されている。

以下のアトリビュートでは、フォーマットパターンに含まれる文字の解釈を制御するとともに、数値のフォーマット結果に現れる文字を規定する。

以下のアトリビュートでは、フォーマットパターンに含む文字の解釈を制御する。

以下のアトリビュートでは、数値をフォーマットした結果に現れる文字または文字列を指定する。

12.4 その他の追加の関数

関数: node-set current()

current 関数は、カレントノードを唯一のメンバとして持つノード集合を返す。 最も外側の式 (他の式の内部に現れない式) については、カレントノードは常にコンテキストノードと同じ意味である。 従って、以下の記述間の関係が成り立つ。

<xsl:value-of select="current()"/>

上記の記述は以下の記述と同じ意味を持つ。

<xsl:value-of select="."/>

ただし角括弧内では、通常、カレントノードとコンテキストノードは異なっている。 以下に例を示す。

<xsl:apply-templates select="//glossary/item[@name=current()/@ref]"/>

上記の記述では、親エレメントが glossary であり、なおかつ name アトリビュートの値がカレントノードの ref アトリビュートの値と等しい、すべての item エレメントを処理する。 この記述の意味は、以下の記述とは異なる。

<xsl:apply-templates select="//glossary/item[@name=./@ref]"/>

上記の記述は以下の記述と同じ意味である。

<xsl:apply-templates select="//glossary/item[@name=@ref]"/>

この記述では、親エレメントが glossary であり、なおかつname アトリビュートと ref アトリビュートの値が等しい、すべての item エレメントを処理することになる。

current 関数をパターン内で使用した場合はエラーである。

関数: string unparsed-entity-uri(string)

unparsed-entity-uri 関数は、コンテキストノードと同じドキュメントに含まれる、指定した名前を持つパース対象外エンティティの URI を返す ([3.3 パース対象外エンティティ] を参照)。 パース対象外エンティティが存在しない場合は、空の文字列を返す。

関数: string generate-id(node-set?)

generate-id 関数は、引数に指定されたノード集合から、ドキュメント順で最初のノードをユニークに識別する文字列を返す。 ユニークな識別子は ASCII の英数字から成り、アルファベット文字を先頭に持たなければならない (must)。 従って、この文字列は、シンタックス上は XML の名前である。実装は、特定のノードには常に同じ識別子を生成し、異なるノードには常に異なる識別子を生成する限り、どのような方法で識別子を生成してもよい。 実装は、あるドキュメントが変換されるごとに同一の識別子を生成する義務はない。 生成されるユニークな識別子が、ソースドキュメント内で指定されているユニークな ID とは別個のものであるという保証はない。 引数に指定されたノード集合が空の場合には、空の文字列を返す。 引数を省略した場合は、デフォルトとしてコンテキストノードを使用する。

関数: object system-property(string)

引数は QName の文字列に評価されなければならない (must)。QName は、式のスコープに含まれるネームスペース宣言を用いて名前に展開される。 system-property 関数は、名前で識別されるシステムプロパティの値を表すオブジェクトを返す。 システムプロパティが存在しない場合には、空の文字列を返すべきである。

実装は、以下の、XSLT ネームスペース内にあるシステムプロパティを提供しなければならない (must)。

13 メッセージ


<xsl:message
  terminate = "yes" | "no">
  
</xsl:message>

xsl:message インストラクションは、XSLT プロセッサに固有の形式でメッセージを送信する。xsl:message インストラクションのコンテンツはテンプレートである。xsl:message は、そのコンテンツをインスタンス化することによってインスタンス化され、XML のフラグメントを生成する。この XML フラグメントがメッセージのコンテンツになる。

注: XSLT プロセッサが xsl:message を実装する場合、警告ボックスのポップアップ、またはログファイルへの書き込みという方法を取ってもよい。

terminate アトリビュートに yes を指定している場合、XSLT プロセッサはメッセージの送信後に処理を終了すべきである。 デフォルト値は no である。

ローカライズを行う便利な方法のひとつは、ローカライズ済みの情報 (メッセージのテキストなど) を XML ドキュメントに挿入することである。この XML ドキュメントは、スタイルシートへの追加入力ファイルとなる。 たとえば L という言語のメッセージを、resources/L.xml という名前の XML ファイルに以下のフォームで保存してあるとする。

<messages>
  <message name="problem">A problem was detected.</message>
  <message name="error">An error was detected.</message>
</messages>

スタイルシートは、以下の処理手順を用いてメッセージをローカライズできる。

<xsl:param name="lang" select="en"/>
<xsl:variable name="messages"
  select="document(concat('resources/', $lang, '.xml'))/messages"/>
<xsl:template name="localized-message">
  <xsl:param name="name"/>
  <xsl:message>
    <xsl:value-of select="$messages/message[@name=$name]"/>
  </xsl:message>
</xsl:template>
<xsl:template name="problem">
  <xsl:call-template name="localized-message"/>
    <xsl:with-param name="name">problem</xsl:with-param>
  </xsl:call-template>
</xsl:template>

14 拡張機能

XSLT は、拡張エレメントおよび拡張関数の2種類の拡張を認めている。

このバージョンの XSLT では、拡張機能の実装を定義するためのメカニズムを提供していない。 このため、XSLT 実装間での相互利用が必須の XSLT スタイルシートは (must)、特定の拡張機能に依存した記述を使用できない。 XSLT では、XSLT スタイルシート側に、処理する側の XSLT プロセッサが特定の拡張機能を実装しているかどうかを判定し、拡張機能を使用できない場合の処理を指定できるメカニズムを提供している。 これらのメカニズムを XSLT スタイルシート側で慎重に利用すれば、拡張機能を活用しながら、XSLT のあらゆる実装を使用してスタイルシートを処理できる。

14.1 拡張エレメント

エレメントを拡張するメカニズムにより、ネームスペースを拡張ネームスペースとして指定できる。 あるネームスペースを拡張ネームスペースとして指定した場合、そのネームスペースに所属する名前を持つエレメントがテンプレートに現れると、そのエレメントはリテラル結果エレメントとしてではなく、インストラクションとして扱われる。 このネームスペースは、インストラクションのセマンティクスを決定する。

注: xsl:stylesheet エレメントの子であるエレメントはテンプレート内に現れないため、XSLT 以外のトップレベルエレメントは、ここで定義している拡張エレメントには該当せず、このセクションの内容にも全く当てはまらない。

あるネームスペースを拡張ネームスペースとして指定するには、xsl:stylesheet エレメントで extension-element-prefixes アトリビュートを使用するか、リテラル結果エレメントまたは拡張エレメントで xsl:extension-element-prefixes アトリビュートを使用する。 これらのアトリビュート値は、どちらもネームスペースのプレフィックスを空白で区切って記述したリストである。 各プレフィックスにバインドされているネームスペースは、拡張ネームスペースとして指定される。 extension-element-prefixes アトリビュートまたは xsl:extension-element-prefixes アトリビュートを持つエレメントのプレフィックスに、バインドされたネームスペースがない場合はエラーである。 ネームスペースのプレフィックスのリストに #default を含めることにより、デフォルトのネームスペース (xmlns を用いて宣言されたもの) を拡張ネームスペースとして指定してもよい。 ネームスペースの拡張ネームスペースとしての指定は、extension-element-prefixes アトリビュートまたは xsl:extension-element-prefixes アトリビュートを持つエレメントをルートとするスタイルシートのサブツリー内部で効力を持つ。xsl:stylesheet エレメントをルートとするサブツリーでは、その xsl:stylesheet エレメントの子がインポートまたはインクルードを行ったスタイルシートは指定の効力が及ぶ範囲に含まれない。

XSLT プロセッサが特定の拡張エレメントに対応する実装を備えていない場合、element-available 関数はそのエレメントの名前に偽を返さなければならない (must)。 このような拡張エレメントをインスタンス化した場合、XSLT プロセッサは [15 フォールバック] で解説しているように、そのエレメントに対するフォールバックを実行しなければならない (must)。 XSLT プロセッサは、対応する実装を備えていない拡張エレメントがテンプレートに含まれているだけでエラーを通知してはならない (must)。

XSLT プロセッサが特定の拡張エレメントに対応する実装を備えている場合、element-available 関数はそのエレメントの名前に対して真を返さなければならない (must)。

14.2 拡張関数

FunctionCall に含まれるある FunctionNameNCName でない (つまりコロンを含む) 場合、この FunctionName は拡張関数の呼び出しとして扱われる。 この FunctionName は評価コンテキストのネームスペース宣言を用いて名前に展開される。

XSLT プロセッサが特定の名前の拡張関数に対応する実装を備えていない場合、function-available 関数はその名前に対して偽を返さなければならない (must)。 このような拡張関数が式に現れ、実際に呼び出された場合、XSLT プロセッサはエラーを通知しなければならない (must)。 XSLT プロセッサは、対応する実装を備えていない拡張関数が式に含れているだけでエラーを通知してはならない (must)。

XSLT プロセッサが特定の名前の拡張関数に対応する実装を備えている場合、function-available 関数はその名前に対して真を返さなければならない (must)。 このような拡張機能を呼び出すと、XSLT プロセッサは実装を呼び出し、関数呼び出しの引数を渡さなければならない (must)。実装から返された結果は、その関数呼び出しの結果として返される。

15 フォールバック


<xsl:fallback>
  
</xsl:fallback>

通常、xsl:fallback エレメントをインスタンス化しても何も実行されないが、XSLT プロセッサがあるインストラクションエレメントに対してフォールバックを実行するときに、そのインストラクションエレメントの子として xsl:fallback が1つまたは複数存在する場合には、それぞれの xsl:fallback 子エレメントのコンテンツを順次インスタンス化しなければならない (must)。その他の場合は、エラーを通知しなければならない (must)。xsl:fallback エレメントのコンテンツはテンプレートである。

xsl:choose インストラクションおよび xsl:if インストラクションと同時に以下の関数を使用すると、特定のエレメントまたは関数を利用できない場合にスタイルシートの挙動を明示的に制御できる。

関数: boolean element-available(string)

引数は QName の文字列に評価されなければならない (must)。この QName は、式のスコープに含まれるネームスペース宣言を用いて展開された名前に展開される。 element-available 関数は、展開された名前がインストラクションの名前の場合にのみ真を返す。 展開された名前が XSLT ネームスペース URI と同じネームスペース URI を持つ場合、XSLT が定義するエレメントを参照する。 その他の場合は拡張エレメントを参照する。 展開された名前が null のネームスペース URI を持つ場合、element-available 関数は偽を返す。

関数: boolean function-available(string)

引数は QName の文字列に評価されなければならない (must)。この QName は、式のスコープに含まれるネームスペース宣言を用いて展開された名前に展開される。 function-available 関数は、展開された名前が関数の名前として関数ライブラリに含まれる場合にのみ真を返す。 展開された名前が null 以外のネームスペース URI を持つ場合、拡張関数を参照する。その他の場合には、XPath または XSLT が定義する関数を参照する。

16 出力


<xsl:output
  method = "xml" | "html" | "text" | qname-but-not-ncname
  version = nmtoken
  encoding = string
  omit-xml-declaration = "yes" | "no"
  standalone = "yes" | "no"
  doctype-public = string
  doctype-system = string
  cdata-section-elements = qnames
  indent = "yes" | "no"
  media-type = string />

XSLT プロセッサは、バイトのシーケンスとして結果ツリーを出力してもよいが、この形で出力する機能は必須ではない ([17 適合性] を参照)。xsl:output エレメントを使用すると、結果ツリーの出力方法をスタイルシートの作成時に指定できる。 ある XSLT プロセッサが結果ツリーを出力する場合には xsl:output エレメントで指定されたとおりに出力すべきである。ただし、結果ツリーの出力は必須ではない。

xsl:output エレメントを記述できるのは、トップレベルエレメントの場合だけである。

xsl:outputmethod アトリビュートでは、結果ツリーの出力時に使用されるはずの全体的なメソッド (訳注:フォーマット方式) を指定する。 この値は QName でなければならない (must)。QName にプレフィックスがない場合には、この文書で規定する出力メソッドであると判定される。この場合 QName は xmlhtml、または text のいずれかでなければならない (must)。 QName にプレフィックスがある場合には、QName[2.4 修飾名] で解説しているように展開された名前に展開され、この展開された名前によって出力メソッドを特定する。展開された名前からメソッドを特定するメカニズムについてはこの文書では規定していない。

method アトリビュートのデフォルトは、以下のように選択される。 選択条件を以下に示す。

以上の条件を満たすと、デフォルトの出力メソッドは html になる。それ以外の場合の出力メソッドは xml になる。 デフォルトの出力メソッドは、xsl:output エレメントの指定がない場合や、指定する xsl:output エレメントのいずれにも method アトリビュートの値の指定がない場合に使用されるべきである。

xsl:output のその他のアトリビュートには、指定済みの出力メソッド用のパラメータを指定する。 使用できるアトリビュートを以下に示す。

アトリビュートのセマンティクスに関する詳細は、各アトリビュートの適用先となる出力メソッドごとに説明する。 アトリビュートのセマンティクスについての説明が各出力メソッドにない場合は、その出力メソッドには適用できない。

スタイルシートには複数の xsl:output エレメントを記述してもよい。また、xsl:output エレメントを持つ他のスタイルシートのインクルードやインポートもできる。 スタイルシートに現れるすべての xsl:output エレメントは、1つの有効な xsl:output エレメントにマージされる。 cdata-section-elements アトリビュートについては、指定された値全体の和集合が有効な値になる。 その他のアトリビュートについては、指定された値のうち最高のインポートの優先順位を持つものが有効な値になる。 1つのアトリビュートに対して最高の優先順位を持つ値が複数存在する場合はエラーである。 この場合、XSLT プロセッサはエラーを通知してもよい。エラーを通知しない場合には、スタイルシートの最後方に現れる値を使用して、エラーから回復すべきである。 xsl:output エレメントがマージされた後に、アトリビュートにデフォルト値が設定される。各出力メソッドでのアトリビュートのデフォルト値は、異なる場合がある。

16.1 XML 出力メソッド

xml 出力メソッドは、結果ツリーをウェルフォームド XML 外部一般パース対象エンティティとして出力する。 結果ツリーのルートノードが、1つのエレメントを子として持ち、テキストノードを1つも子として持たない場合、このエンティティはウェルフォームド XML ドキュメントにもなる。 このようなエンティティを、以下に示す小さな XML ドキュメントラッパーで参照する場合、

<!DOCTYPE doc [
<!ENTITY e SYSTEM "entity-URI">
]>
<doc>&e;</doc>

(上記の entity-URI はエンティティの URI を示している) ラッパードキュメント全体が XML ネームスペース勧告 (XML Namespaces Recommendation) [XML Names] に適合するウェルフォームド XML ドキュメントになるべきである。さらに、出力は以下のようになるべきである。[3 データモデル] で定義されているようにラッパーを XML 文書としてパースして、ドキュメントエレメントを削除してその子エレメントをルートノードの子とすることにより新しいツリーが構築したとき、その新しいツリーは、次に示す例外を除いて、リザルトツリーと同じでなければならない。

doctype-system アトリビュートの指定によって XSLT プロセッサがドキュメント型宣言を生成する場合があるが、このような場合には、生成したドキュメント型宣言を削除したエンティティに対して、上記の要件が適用される。

version アトリビュートには、結果ツリーの出力に使用する XML のバージョンを指定する。 XSLT プロセッサは、サポートしていない XML のバージョン指定を受け取った場合には、サポートしているバージョンを使用すべきである。 (XML 宣言が出力される場合の ) XML 宣言に出力されるバージョンは、XSLT プロセッサが結果ツリーの出力に使用したバージョンに対応すべきである。 version アトリビュートの値は、XML 勧告 [XML] のプロダクション VersionNum に該当すべきである。 デフォルト値は 1.0 である。

encoding アトリビュートには、結果ツリーの出力処理に使用したいエンコーディング方式を指定する。 XSLT プロセッサは、値 UTF-8 および UTF-16 をサポートしなければならない。 その他の値については、XSLT プロセッサがサポートしていないエンコーディングを指定した場合、XSLT プロセッサはエラーを通知してもよい。エラーを通知しない場合には、その代わりに UTF-8 または UTF-16 を使用すべきである。 XSLT プロセッサは、XML 勧告 [XML] のプロダクション EncName に該当しない名前のエンコーディングを使用してはならない (must)。 encoding アトリビュートを指定していない場合、XSLT プロセッサは UTF-8 または UTF-16 のいずれかを使用すべきである。 結果ツリーには、XSLT プロセッサが出力に使用するエンコーディングでは表現できない文字を含む場合もある。 この場合、XML がキャラクターリファレンスを認識するコンテキスト内に (つまりアトリビュートノードまたはテキストノードの値内に) その文字が現れるのであれば、キャラクターリファレンスとして出力すべきである。それ以外の場合 (たとえばその文字がエレメントの名前に現れる場合) には、XSLT プロセッサはエラーを通知すべきである。

indent アトリビュートが値 yes を持つ場合、xml 出力メソッドは、結果を見栄え良くインデント (字下げ) するため、 結果ツリー内の空白に (ソースドキュメントまたはスタイルシートから削除された空白などを基準にできる場合はこれを基準に) 空白を加えて出力してもよい。indent アトリビュートの値が no の場合は、追加した空白を出力すべきではない。 デフォルト値は no である。 xml 出力メソッドで使用する空白追加出力用のアルゴリズムは、xsl:text だけを空白を保持するエレメントの集合とし、[3.4 空白の削除] で解説しているプロセスによって空白を削除する際に、空白を追加してもしなくても、同一の結果になることを保証するものであるべきである。

注: 一般に、混合コンテンツを持つエレメント型を含むドキュメント型に、indent="yes" を使用すると問題が起こる可能性が高い。

cdata-section-elements アトリビュートの値は、空白で区切った QName のリストである。 これらの QName は、各 QName が現れる xsl:output エレメントで有効となっているネームスペース宣言を用いて展開された名前に展開される。プレフィックスを持たない QName は、デフォルトのネームスペースが存在する場合には、そのデフォルト値を使用する。 この展開処理は、複数の xsl:output エレメントを有効な xsl:output エレメントにマージする前に行われる。 リストのメンバにテキストノードの親の展開された名前を含む場合、そのテキストノードを CDATA セクションとして出力すべきである。 以下に例を示す。

<xsl:output cdata-section-elements="example"/>

上記の記述は、以下のように記述されたリテラル結果エレメント、

<example>&lt;foo></example>

または以下のように記述されたリテラル結果エレメントを、

<example><![CDATA[<foo>]]></example>

次のように出力する。

<example><![CDATA[<foo>]]></example>

テキストノードが文字シーケンス ]]> を含む場合、処理中の CDATA セクションを ]] の後ろで閉じ、新しい CDATA セクションを > の前で開くべきである。たとえば、スタイルシートに以下のリテラル結果エレメントが記述されているとする。

<example>]]&gt;</example>

これは、以下のように出力される。

<example><![CDATA[>]]></example>

結果ツリーの出力に使用するキャラクターエンコーディングで表現できない文字をテキストノードに含む場合、処理中の CDATA セクションをその文字の前で閉じるべきである。その文字をキャラクターリファレンスまたはエンティティリファレンスを使って出力し、テキストノード内で後に続く文字には新しい CDATA セクションを開くべきである。

cdata-section-elements アトリビュートで明示的に指定したテキストノードは、CDATA セクションを用いて出力すべきだが、それ以外のテキストノードを CDATA セクションで出力すべきではない。

omit-xml-declaration アトリビュートの値が yes でない場合、xml 出力メソッドは XML 宣言を出力すべきである。XML 宣言には、バージョン情報とエンコーディング宣言の両方を出力すべきである。standalone アトリビュートを指定している場合、XML 宣言には、standalone アトリビュート値と同じ値を持つスタンドアロンドキュメントの宣言を含めるべきである。 その他の場合は、スタンドアロンドキュメント宣言を含めるべきではない。これにより、XML 宣言 (ドキュメントエンティティの先頭での記述が許されている) であるとともに、テキスト宣言 (外部一般パース対象エンティティの先頭での記述が許されている) でもあることを保証する。

doctype-system アトリビュートを指定している場合、xml 出力メソッドは最初のエレメントの直前にドキュメント型宣言を出力すべきである。 つまり、<!DOCTYPE に続く名前は、最初のエレメントの名前となる。 doctype-public アトリビュートを同時に指定している場合、xml 出力メソッドは PUBLIC に続けて公開識別子を出力し、次にシステム識別子を出力すべきである。その他の場合は、SYSTEM に続けてシステム識別子を出力すべきである。 内部のサブセットは空であるべきである。doctype-public アトリビュートは、doctype-system アトリビュートを指定していない場合は無視される。

media-type アトリビュートは xml 出力メソッドに適用できる。 media-type アトリビュートのデフォルト値は text/xml である。

16.2 HTML 出力メソッド

html 出力メソッドは結果ツリーを HTML として出力する。以下に例を示す。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="/">
  <html>
   <xsl:apply-templates/>
  </html>
</xsl:template>
...
</xsl:stylesheet>

version アトリビュートは、HTML のバージョンを示す。デフォルト値は 4.0 である。このデフォルト値は、結果ツリーを HTML 4.0 勧告 (HTML 4.0 Recommendation) [HTML] に適合する HTML で出力するように指定している。

html 出力メソッドは、エレメントの展開された名前が null のネームスペース URI を持つ場合を除き、xml 出力メソッドと異なる方法でエレメントを出力すべきではない。展開された名前が null 以外のネームスペース URI を持つエレメントは、XML として出力すべきである。 展開された名前が null のネームスペース URI を持つが、ローカルパートが HTML エレメントの名前であると認識されないエレメントは、span などの空でないインラインエレメントと同じ方法で出力すべきである。

html 出力メソッドは空エレメントのエンドタグを出力すべきではない。 HTML 4.0 の空エレメントは、areabasebasefontbrcolframehrimginputisindexlinkmeta、および param である。 たとえば、スタイルシートに <br/> または <br></br> と記述されたエレメントは、<br> と出力される。

html 出力メソッドは、大文字と小文字のどちらを使用しているかに関わらず、HTML エレメントの名前を認識すべきである。たとえば、エレメントの名前が brBR、または Br の場合、これらはすべて HTML の br エレメントであると認識され、エンドタグなしで出力される。

html 出力メソッドは、script および style エレメントのコンテンツに対するエスケープ処理を実行すべきではない。 たとえば、以下に示す2つの例のようなリテラル結果エレメントがスタイルシートに含まれると仮定する。

または、

これらは、以下のように出力される。

html 出力メソッドでは、アトリビュート値に現れる文字 < をエスケープすべきではない。

indent アトリビュートの値が yes の場合、html 出力メソッドは、HTML ユーザーエージェントによるレンダリング処理に影響を与えない範囲で、結果ツリーの出力時に空白を追加または削除してもよい。デフォルト値は yes である。

html 出力メソッドは、HTML 4.0 勧告セクション B.2.1 で推奨する方法を用いて、URI アトリビュートの値が持つ非 ASCII 文字をエスケープすべきである。

html 出力メソッドは、ある文字に対するキャラクターエンティティリファレンスが使用中の HTML のバージョンで定義されていれば、キャラクターエンティティリファレンスを使用してその文字を出力してもよい。

html 出力メソッドは、?> ではなく > を使用してプロセッシングインストラクションを終了すべきである。

また、html 出力メソッドは、ブール型のアトリビュート (アトリビュートの名前と同じ値のみが、値として許されるアトリビュート) を最小化した形で出力すべきである。たとえば、スタイルシートに以下のスタートタグが記述されている場合、

<OPTION selected="selected">

これは以下のように出力される。

<OPTION selected>

html 出力メソッドは { 文字の直前のアトリビュート値に現れる & 文字をエスケープすべきではない (HTML 4.0 勧告の セクション B.7.1 を参照)。 たとえば、スタイルシートに以下のスタートタグが記述されている場合、

<BODY bgcolor='&amp;{{randomrbg}};'>

これは以下のように出力される。

<BODY bgcolor='&{randomrbg};'>

encoding アトリビュートでは、HTML 出力メソッドに使用したいエンコーディングを指定する。HEAD エレメントがある場合、html 出力メソッドは HEAD エレメントのスタートタグの直後に META エレメントを追加して、実際に使われるキャラクターエンコーディングを指定すべきである。 以下に例を示す。

<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
...

結果ツリーには、XSLT プロセッサが出力に使用しているエンコーディングで表現できない文字が含まれていてもよい。 この場合、HTML がキャラクターリファレンスを認識するコンテキストにその文字が現れたら、その文字をキャラクターエンティティリファレンスまたは十進コードによるキャラクターリファレンス (decimal numeric character reference)で出力すべきである。その他の場合 (たとえば script エレメントや style エレメント内、またはコメント内にその文字が現れた場合) には、XSLT プロセッサはエラーを通知すべきである。

doctype-public アトリビュートまたは doctype-system アトリビュートを指定している場合、html 出力メソッドは最初のエレメントの直前にドキュメント型宣言を出力すべきである。 <!DOCTYPE に続く名前は、HTML または html である。doctype-public アトリビュートを指定している場合、出力メソッドは PUBLIC を出力し、それに続いて指定している公開識別子を出力すべきである。doctype-system アトリビュートを同時に指定している場合は、公開識別子に続けてシステム識別子も出力すべきである。 doctype-public アトリビュートは指定していないが、doctype-system アトリビュートを指定している場合、出力メソッドは SYSTEM を出力し、それに続いて指定されているシステム識別子を出力すべきである。

media-type アトリビュートは html 出力メソッドに適用できる。 デフォルト値は text/html である。

16.3 テキスト出力メソッド

テキスト出力メソッドによる結果ツリーの出力は、エスケープ処理を行わず、結果ツリーの各テキストノードの文字列値をドキュメント順に出力する。

media-type アトリビュートはテキスト出力メソッドに適用できる。media-type アトリビュートのデフォルト値は text/plain である。

encoding アトリビュートには、テキスト出力メソッドが文字のシーケンスをバイトのシーケンスに変換する際に使用するエンコーディングを指定する。デフォルト値はシステムによって異なる。XSLT プロセッサが出力に使用しているエンコーディングで表現できない文字が結果ツリーに含まれている場合、XSLT プロセッサはエラーを通知すべきである。

16.4 出力エスケープの無効化

通常、xml 出力メソッドがテキストノードを出力する際には、& や < を (あるいは他の文字も含めて) エスケープする。このような処理を行うことにより、出力結果は必ずウェルフォームド XML になる。ただし出力結果が、完全ではないが大部分はウェルフォームド XML であると便利な場合もある。たとえば、ウェルフォームドでないセクションを出力結果に含め、その部分を XML 非対応の次の処理プロセスでウェルフォームド XML に変換しようとする場合などである。 このため XSLT では、出力エスケープを無効化するメカニズムを提供している。 xsl:value-of エレメントや xsl:text エレメントには、disable-output-escaping アトリビュートを記述できる。使用できる値は yes または no であり、デフォルト値は no である。値が yes の場合には、xsl:value-of エレメントまたは xsl:text エレメントをインスタンス化して生成したテキストノードを、エスケープ処理なしで出力すべきである。 以下に例を示す。

<xsl:text disable-output-escaping="yes">&lt;</xsl:text>

この記述は1個の文字 < を生成する。

結果ツリーのテキストノード以外の用途で使用するテキストノードに対して、出力エスケープを無効にした場合はエラーである。 従って、コメント、プロセッシングインストラクション、またはアトリビュートノードの文字列値の生成に使用する、xsl:value-of エレメントや xsl:text エレメントに対して出力エスケープを無効にした場合もエラーである。また、エスケープ処理を無効化したテキストノードを結果ツリーフラグメントに含む状態で、結果ツリーフラグメントを数値または文字列に変換した場合はエラーである。 どちらの場合にも、XSLT プロセッサはエラーを通知してもよい。エラーを通知しない場合には、disable-output-escaping アトリビュートを無視してエラーから回復しなければならない (must)。

disable-output-escaping アトリビュートは、xml 出力メソッドの場合と同様に、html 出力メソッドでも使用できる。 テキスト出力メソッドでは、出力のエスケープ処理を全く行わないため、disable-output-escaping アトリビュートを無視する。

XSLT プロセッサは、結果ツリーの出力を制御する場合にのみ、出力エスケープを無効にできるが、 例外もある。 たとえば、結果ツリーを出力するかわりに別の XSLT 変換のソースツリーとして使用する場合がある。 XSLT プロセッサでは、出力エスケープの無効化のサポートは必須ではない。 xsl:value-of または xsl:text が出力エスケープの無効化を指定しても、XSLT プロセッサが出力エスケープの無効化をサポートしていない場合、XSLT プロセッサはエラーを通知してもよい。エラーを通知しない場合には、出力エスケープを無効化しないようにしてエラーから回復しなければならない (must)。

XSLT プロセッサが出力に使用しているエンコーディングで表現できない文字に対して出力エスケープが無効になっている場合、XSLT プロセッサはエラーを通知してもよい。エラーを通知しない場合には、出力エスケープを無効化しないようにしてエラーから回復しなければならない (must)。

出力エスケープの無効化を使用すると、ウェルフォームド XML でない結果になる場合があることや、この機能をサポートしない XSLT プロセッサもあることから、この機能は他に選択肢がない場合に限って使用すべきである。

17 適合性

XSLT プロセッサが規定に適合するには、この文書で規定しているとおりに、スタイルシートを使用してソースツリーを結果ツリーに変換できなければならない (must)。 適合する XSLT プロセッサには、XML またはその他のフォームで結果を出力する機能は必要ではない。

注: XSLT プロセッサのベンダは、結果ツリーを XML として出力可能にすることや、DOM や SAX などの標準 API 経由で結果ツリーへのアクセスを提供することによって、プロセッサが適合性を満たすように動作することを検証する手段を提供することが強く推奨されている。

適合する XSLT プロセッサは、「エラーを通知しなくてよい」とこの文書内で明示している場合以外は、すべてのエラーを通知しなければならない (must)。 適合する XSLT プロセッサは、通知したエラーから回復してもよいが、エラーからの回復は適合性の要件ではない。

適合する XSLT プロセッサは、スタイルシートの処理によって消費される処理のリソースに制限を設けてもよい。

18 ノテーション

XSLT で定義する各エレメント型の仕様については、そのエレメント型に属するエレメントをモデル形式で示したシンタックスの要約をその先頭に記述している。 シンタックスの要約におけるノテーションの意味は、以下のとおりである。


A 参考文献

A.1 基準となる参考文献

XML
World Wide Web Consortium (W3C). Extensible Markup Language (XML) 1.0. W3C Recommendation.参照先 http://www.w3.org/TR/1998/REC-xml-19980210
XML Names
World Wide Web Consortium (W3C). Namespaces in XML. W3C Recommendation. 参照先 http://www.w3.org/TR/REC-xml-names
XPath
World Wide Web Consortium (W3C). XML Path Language. W3C Recommendation. 参照先 REC-xpath-19991116-jpn.htm

A.2 その他の参考文献

CSS2
World Wide Web Consortium (W3C). Cascading Style Sheets, level 2 (CSS2) . W3C Recommendation. 参照先 http://www.w3.org/TR/1998/REC-CSS2-19980512
DSSSL
International Organization for Standardization (国際標準化機構、ISO), International Electrotechnical Commission (国際電気標準会議、IEC). ISO/IEC 10179:1996. Document Style Semantics and Specification Language (DSSSL). International Standard.
HTML
World Wide Web Consortium (W3C). HTML 4.0 specification. W3C Recommendation. 参照先 http://www.w3.org/TR/REC-html40
IANA
Internet Assigned Numbers Authority (IANA). Character Sets. 参照先 ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets
RFC2278
N. Freed, J. Postel. IANA Charset Registration Procedures. IETF RFC 2278. 参照先 http://www.ietf.org/rfc/rfc2278.txt.
RFC2376
E. Whitehead, M. Murata. XML Media Types . IETF RFC 2376. 参照先 http://www.ietf.org/rfc/rfc2376.txt
RFC2396
T. Berners-Lee, R. Fielding, and L. Masinter. Uniform Resource Identifiers (URI): Generic Syntax. IETF RFC 2396. 参照先 http://www.ietf.org/rfc/rfc2396.txt
UNICODE TR10
Unicode Consortium. Unicode Technical Report #10 Unicode Collation Algorithm. Unicode Technical Report. 参照先 http://www.unicode.org/unicode/reports/tr10/index.html
XHTML
World Wide Web Consortium (W3C). XHTML 1.0: The Extensible HyperText Markup Language. W3C Proposed Recommendation. 参照先 http://www.w3.org/TR/xhtml1
XPointer
World Wide Web Consortium (W3C). XML Pointer Language (XPointer). W3C Working Draft. 参照先 http://www.w3.org/TR/xptr
XML Stylesheet
World Wide Web Consortium (W3C). Associating stylesheets with XML documents. W3C Recommendation. 参照先 http://www.w3.org/TR/xml-stylesheet
XSL
World Wide Web Consortium (W3C). Extensible Stylesheet Language (XSL). W3C Working Draft. 参照先 http://www.w3.org/TR/WD-xsl

B エレメントのシンタックスの要約


<xsl:apply-imports />


<xsl:apply-templates
  select = node-set-expression
  mode = qname>
  
</xsl:apply-templates>


<xsl:attribute
  name = { qname }
  namespace = { uri-reference }>
  
</xsl:attribute>


<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
  
</xsl:attribute-set>


<xsl:call-template
  name = qname>
  
</xsl:call-template>


<xsl:choose>
  
</xsl:choose>


<xsl:comment>
  
</xsl:comment>


<xsl:copy
  use-attribute-sets = qnames>
  
</xsl:copy>


<xsl:copy-of
  select = expression />


<xsl:decimal-format
  name = qname
  decimal-separator = char
  grouping-separator = char
  infinity = string
  minus-sign = char
  NaN = string
  percent = char
  per-mille = char
  zero-digit = char
  digit = char
  pattern-separator = char />


<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  
</xsl:element>


<xsl:fallback>
  
</xsl:fallback>


<xsl:for-each
  select = node-set-expression>
  
</xsl:for-each>


<xsl:if
  test = boolean-expression>
  
</xsl:if>

<xsl:import
  href = uri-reference />


<xsl:include
  href = uri-reference />


<xsl:key
  name = qname
  match = pattern
  use = expression />


<xsl:message
  terminate = "yes" | "no">
  
</xsl:message>


<xsl:namespace-alias
  stylesheet-prefix = prefix | "#default"
  result-prefix = prefix | "#default" />


<xsl:number
  level = "single" | "multiple" | "any"
  count = pattern
  from = pattern
  value = number-expression
  format = { string }
  lang = { nmtoken }
  letter-value = { "alphabetic" | "traditional" }
  grouping-separator = { char }
  grouping-size = { number } />

<xsl:otherwise>
  
</xsl:otherwise>


<xsl:output
  method = "xml" | "html" | "text" | qname-but-not-ncname
  version = nmtoken
  encoding = string
  omit-xml-declaration = "yes" | "no"
  standalone = "yes" | "no"
  doctype-public = string
  doctype-system = string
  cdata-section-elements = qnames
  indent = "yes" | "no"
  media-type = string />


<xsl:param
  name = qname
  select = expression>
  
</xsl:param>


<xsl:preserve-space
  elements = tokens />


<xsl:processing-instruction
  name = { ncname }>
  
</xsl:processing-instruction>

<xsl:sort
  select = string-expression
  lang = { nmtoken }
  data-type = { "text" | "number" | qname-but-not-ncname }
  order = { "ascending" | "descending" }
  case-order = { "upper-first" | "lower-first" } />


<xsl:strip-space
  elements = tokens />

<xsl:stylesheet
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  
</xsl:stylesheet>


<xsl:template
  match = pattern
  name = qname
  priority = number
  mode = qname>
  
</xsl:template>


<xsl:text
  disable-output-escaping = "yes" | "no">
  
</xsl:text>

<xsl:transform
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  
</xsl:transform>


<xsl:value-of
  select = string-expression
  disable-output-escaping = "yes" | "no" />



<xsl:variable
  name = qname
  select = expression>
  
</xsl:variable>

<xsl:when
  test = boolean-expression>
  
</xsl:when>

<xsl:with-param
  name = qname
  select = expression>
  
</xsl:with-param>

C XSLT スタイルシート用 DTD フラグメント (規定外)

注: この DTD フラグメントは、基準となる規定ではない。規定でない理由は、XML 1.0 の DTD は XML ネームスペースをサポートしていないため、XSLT スタイルシートで認めている構造を正しく記述できないためである。

特定の結果 DTD のインスタンスを生成する XSLT スタイルシート用 DTD を構築するため、後述のエンティティを使用できる。 このエンティティを参照するには、スタイルシート用の DTD に、許される結果エレメント型を列挙した、 result-elements パラメータエンティティを定義しておかなければならない (must)。 以下に例を示す。

<!ENTITY % result-elements "
  | fo:inline-sequence
  | fo:block
">

このような結果エレメントは、アトリビュートとして xsl:use-attribute-sets および xsl:extension-element-prefixes を持つことを宣言しておくべきである。 以降に示すエンティティでは、この目的で result-element-atts パラメータを宣言している。 XSLT が結果エレメントとして許しているコンテンツは、 %template; のコンテンツモデルを持つように後述のエンティティによって宣言されている、 XSLT のエレメントで許容されるコンテンツと同一である。 この DTD では、結果 DTD における制約を反映するために、%template; の場合より制限が多いコンテンツモデルを使用してもよい。

この DTD では、non-xsl-top-level パラメータのエンティティを定義し、XSLT ネームスペース以外のネームスペースからトップレベルエレメントを追加してもよい。

この DTD ではプレフィックス xsl: を使用しているが、これは XSLT のスタイルシートでもこのプレフィックスを使用しなければならないという意味ではない。 以下の DTD で宣言しているすべてのエレメントは、ここに示めしたアトリビュートに加え、名前が xmlns: で始まるアトリビュートや xmlns と同じアトリビュートを持つことができる。

<!ENTITY % char-instructions "
  | xsl:apply-templates
  | xsl:call-template
  | xsl:apply-imports
  | xsl:for-each
  | xsl:value-of
  | xsl:copy-of
  | xsl:number
  | xsl:choose
  | xsl:if
  | xsl:text
  | xsl:copy
  | xsl:variable
  | xsl:message
  | xsl:fallback
">
<!ENTITY % instructions "
  %char-instructions;
  | xsl:processing-instruction
  | xsl:comment
  | xsl:element
  | xsl:attribute
">
<!ENTITY % char-template "
 (#PCDATA
  %char-instructions;)*
">
<!ENTITY % template "
 (#PCDATA
  %instructions;
  %result-elements;)*
">

<!ENTITY % URI "CDATA">

<!ENTITY % pattern "CDATA">

<!ENTITY % avt "CDATA">

<!ENTITY % qname "NMTOKEN">

<!ENTITY % qnames "NMTOKENS">

<!ENTITY % expr "CDATA">

<!ENTITY % char "CDATA">

<!ENTITY % priority "NMTOKEN">
<!ENTITY % space-att "xml:space (default|preserve) #IMPLIED">

<!ENTITY % non-xsl-top-level "">
<!ENTITY % top-level "
 (xsl:import*,
  (xsl:include
  | xsl:strip-space
  | xsl:preserve-space
  | xsl:output
  | xsl:key
  | xsl:decimal-format
  | xsl:attribute-set
  | xsl:variable
  | xsl:param
  | xsl:template
  | xsl:namespace-alias
  %non-xsl-top-level;)*)
">
<!ENTITY % top-level-atts '
  extension-element-prefixes CDATA #IMPLIED
  exclude-result-prefixes CDATA #IMPLIED
  id ID #IMPLIED
  version NMTOKEN #REQUIRED
  xmlns:xsl CDATA #FIXED "http://www.w3.org/1999/XSL/Transform"
  %space-att;
'>

<!ENTITY % result-element-atts '
  xsl:extension-element-prefixes CDATA #IMPLIED
  xsl:exclude-result-prefixes CDATA #IMPLIED
  xsl:use-attribute-sets %qnames; #IMPLIED
  xsl:version NMTOKEN #IMPLIED
'>
<!ELEMENT xsl:stylesheet %top-level;>
<!ATTLIST xsl:stylesheet %top-level-atts;>
<!ELEMENT xsl:transform %top-level;>
<!ATTLIST xsl:transform %top-level-atts;>
<!ELEMENT xsl:import EMPTY>
<!ATTLIST xsl:import href %URI; #REQUIRED>
<!ELEMENT xsl:include EMPTY>
<!ATTLIST xsl:include href %URI; #REQUIRED>
<!ELEMENT xsl:strip-space EMPTY>
<!ATTLIST xsl:strip-space elements CDATA #REQUIRED>
<!ELEMENT xsl:preserve-space EMPTY>
<!ATTLIST xsl:preserve-space elements CDATA #REQUIRED>
<!ELEMENT xsl:output EMPTY>
<!ATTLIST xsl:output
  method %qname; #IMPLIED
  version NMTOKEN #IMPLIED
  encoding CDATA #IMPLIED
  omit-xml-declaration (yes|no) #IMPLIED
  standalone (yes|no) #IMPLIED
  doctype-public CDATA #IMPLIED
  doctype-system CDATA #IMPLIED
  cdata-section-elements %qnames; #IMPLIED
  indent (yes|no) #IMPLIED
  media-type CDATA #IMPLIED
>
<!ELEMENT xsl:key EMPTY>
<!ATTLIST xsl:key
  name %qname; #REQUIRED
  match %pattern; #REQUIRED
  use %expr; #REQUIRED
>
<!ELEMENT xsl:decimal-format EMPTY>
<!ATTLIST xsl:decimal-format
  name %qname; #IMPLIED
  decimal-separator %char; "."
  grouping-separator %char; ","
  infinity CDATA "Infinity"
  minus-sign %char; "-"
  NaN CDATA "NaN"
  percent %char; "%"
  per-mille %char; "&#x2030;"
  zero-digit %char; "0"
  digit %char; "#"
  pattern-separator %char; ";"
>
<!ELEMENT xsl:namespace-alias EMPTY>
<!ATTLIST xsl:namespace-alias
  stylesheet-prefix CDATA #REQUIRED
  result-prefix CDATA #REQUIRED
>
<!ELEMENT xsl:template
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:param)*
>
<!ATTLIST xsl:template
  match %pattern; #IMPLIED
  name %qname; #IMPLIED
  priority %priority; #IMPLIED
  mode %qname; #IMPLIED
  %space-att;
>
<!ELEMENT xsl:value-of EMPTY>
<!ATTLIST xsl:value-of
  select %expr; #REQUIRED
  disable-output-escaping (yes|no) "no"
>
<!ELEMENT xsl:copy-of EMPTY>
<!ATTLIST xsl:copy-of select %expr; #REQUIRED>
<!ELEMENT xsl:number EMPTY>
<!ATTLIST xsl:number
   level (single|multiple|any) "single"
   count %pattern; #IMPLIED
   from %pattern; #IMPLIED
   value %expr; #IMPLIED
   format %avt; '1'
   lang %avt; #IMPLIED
   letter-value %avt; #IMPLIED
   grouping-separator %avt; #IMPLIED
   grouping-size %avt; #IMPLIED
>
<!ELEMENT xsl:apply-templates (xsl:sort|xsl:with-param)*>
<!ATTLIST xsl:apply-templates
  select %expr; "node()"
  mode %qname; #IMPLIED
>
<!ELEMENT xsl:apply-imports EMPTY>

<!ELEMENT xsl:for-each
 (#PCDATA
  %instructions;
  %result-elements;
  | xsl:sort)*
>
<!ATTLIST xsl:for-each
  select %expr; #REQUIRED
  %space-att;
>
<!ELEMENT xsl:sort EMPTY>
<!ATTLIST xsl:sort
  select %expr; "."
  lang %avt; #IMPLIED
  data-type %avt; "text"
  order %avt; "ascending"
  case-order %avt; #IMPLIED
>
<!ELEMENT xsl:if %template;>
<!ATTLIST xsl:if
  test %expr; #REQUIRED
  %space-att;
>
<!ELEMENT xsl:choose (xsl:when+, xsl:otherwise?)>
<!ATTLIST xsl:choose %space-att;>
<!ELEMENT xsl:when %template;>
<!ATTLIST xsl:when
  test %expr; #REQUIRED
  %space-att;
>
<!ELEMENT xsl:otherwise %template;>
<!ATTLIST xsl:otherwise %space-att;>
<!ELEMENT xsl:attribute-set (xsl:attribute)*>
<!ATTLIST xsl:attribute-set
  name %qname; #REQUIRED
  use-attribute-sets %qnames; #IMPLIED
>
<!ELEMENT xsl:call-template (xsl:with-param)*>
<!ATTLIST xsl:call-template
  name %qname; #REQUIRED
>
<!ELEMENT xsl:with-param %template;>
<!ATTLIST xsl:with-param
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>
<!ELEMENT xsl:variable %template;>
<!ATTLIST xsl:variable 
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>
<!ELEMENT xsl:param %template;>
<!ATTLIST xsl:param 
  name %qname; #REQUIRED
  select %expr; #IMPLIED
>
<!ELEMENT xsl:text (#PCDATA)>
<!ATTLIST xsl:text
  disable-output-escaping (yes|no) "no"
>
<!ELEMENT xsl:processing-instruction %char-template;>
<!ATTLIST xsl:processing-instruction 
  name %avt; #REQUIRED
  %space-att;
>
<!ELEMENT xsl:element %template;>
<!ATTLIST xsl:element 
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  use-attribute-sets %qnames; #IMPLIED
  %space-att;
>
<!ELEMENT xsl:attribute %char-template;>
<!ATTLIST xsl:attribute 
  name %avt; #REQUIRED
  namespace %avt; #IMPLIED
  %space-att;
>
<!ELEMENT xsl:comment %char-template;>
<!ATTLIST xsl:comment %space-att;>
<!ELEMENT xsl:copy %template;>
<!ATTLIST xsl:copy
  %space-att;
  use-attribute-sets %qnames; #IMPLIED
>
<!ELEMENT xsl:message %template;>
<!ATTLIST xsl:message
  %space-att;
  terminate (yes|no) "no"
>
<!ELEMENT xsl:fallback %template;>
<!ATTLIST xsl:fallback %space-att;>

D 例 (規定外)

D.1 文書例

以下に示すスタイルシートの例では、簡単な DTD に従うドキュメントを XHTML [XHTML] に変換している。 DTD の内容を以下に示す。

<!ELEMENT doc (title, chapter*)>
<!ELEMENT chapter (title, (para|note)*, section*)>
<!ELEMENT section (title, (para|note)*)>
<!ELEMENT title (#PCDATA|emph)*>
<!ELEMENT para (#PCDATA|emph)*>
<!ELEMENT note (#PCDATA|emph)*>
<!ELEMENT emph (#PCDATA|emph)*>

スタイルシートの内容を以下に示す。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/TR/xhtml1/strict">
<xsl:strip-space elements="doc chapter section"/>
<xsl:output
   method="xml"
   indent="yes"
   encoding="iso-8859-1"
/>
<xsl:template match="doc">
 <html>
   <head>
     <title>
       <xsl:value-of select="title"/>
     </title>
   </head>
   <body>
     <xsl:apply-templates/>
   </body>
 </html>
</xsl:template>
<xsl:template match="doc/title">
  <h1>
    <xsl:apply-templates/>
  </h1>
</xsl:template>
<xsl:template match="chapter/title">
  <h2>
    <xsl:apply-templates/>
  </h2>
</xsl:template>
<xsl:template match="section/title">
  <h3>
    <xsl:apply-templates/>
  </h3>
</xsl:template>
<xsl:template match="para">
  <p>
    <xsl:apply-templates/>
  </p>
</xsl:template>
<xsl:template match="note">
  <p class="note">
    <b>NOTE: </b>
    <xsl:apply-templates/>
  </p>
</xsl:template>
<xsl:template match="emph">
  <em>
    <xsl:apply-templates/>
  </em>
</xsl:template>
</xsl:stylesheet>

上記の前提で、以下の入力ドキュメントを使用する。

<!DOCTYPE doc SYSTEM "doc.dtd">
<doc>
<title>Document Title</title>
<chapter>
<title>Chapter Title</title>
<section>
<title>Section Title</title>
<para>This is a test.</para>
<note>This is a note.</note>
</section>
<section>
<title>Another Section Title</title>
<para>This is <emph>another</emph> test.</para>
<note>This is another note.</note>
</section>
</chapter>
</doc>

上記の入力ドキュメントは以下の結果を生成する。

<html xmlns="http://www.w3.org/TR/xhtml1/strict">
<head>
<title>Document Title</title>
</head>
<body>
<h1>Document Title</h1>
<h2>Chapter Title</h2>
<h3>Section Title</h3>
<p>This is a test.</p>
<p class="note">
<b>NOTE: </b>This is a note.</p>
<h3>Another Section Title</h3>
<p>This is <em>another</em> test.</p>
<p class="note">
<b>NOTE: </b>This is another note.</p>
</body>
</html>

D.2 データ例

以下に、XML で表現されたデータを変換処理する例を示す。この例では、3種類の XSLT スタイルシートを用いて HTML、SVG、および VRML による3種類の異なるデータ表現を生成している。

XML の入力データを以下に示す。

<sales>
        <division id="North">
                <revenue>10</revenue>
                <growth>9</growth>
                <bonus>7</bonus>
        </division>
        <division id="South">
                <revenue>4</revenue>
                <growth>3</growth>
                <bonus>4</bonus>
        </division>
        <division id="West">
                <revenue>6</revenue>
                <growth>-1.5</growth>
                <bonus>2</bonus>
        </division>
</sales>

以下は、簡略化されたシンタックス ([2.3 スタイルシートとしてのリテラル結果エレメント] を参照) で記述した XML の入力データを HTML 形式に変換するスタイルシートである。

<html xsl:version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      lang="en">
    <head>
	<title>Sales Results By Division</title>
    </head>
    <body>
	<table border="1">
	    <tr>
		<th>Division</th>
		<th>Revenue</th>
		<th>Growth</th>
		<th>Bonus</th>
	    </tr>
	    <xsl:for-each select="sales/division">
		
		<xsl:sort select="revenue"
			  data-type="number"
			  order="descending"/>
		<tr>
		    <td>
			<em><xsl:value-of select="@id"/></em>
		    </td>
		    <td>
			<xsl:value-of select="revenue"/>
		    </td>
		    <td>
			
			<xsl:if test="growth &lt; 0">
			     <xsl:attribute name="style">
				 <xsl:text>color:red</xsl:text>
			     </xsl:attribute>
			</xsl:if>
			<xsl:value-of select="growth"/>
		    </td>
		    <td>
			<xsl:value-of select="bonus"/>
		    </td>
		</tr>
	    </xsl:for-each>
	</table>
    </body>
</html>

HTML での出力は以下のようになる。

<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Sales Results By Division</title>
</head>
<body>
<table border="1">
<tr>
<th>Division</th><th>Revenue</th><th>Growth</th><th>Bonus</th>
</tr>
<tr>
<td><em>North</em></td><td>10</td><td>9</td><td>7</td>
</tr>
<tr>
<td><em>West</em></td><td>6</td><td style="color:red">-1.5</td><td>2</td>
</tr>
<tr>
<td><em>South</em></td><td>4</td><td>3</td><td>4</td>
</tr>
</table>
</body>
</html>

以下は、XML の入力データを SVG 形式に変換するスタイルシートである。

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/Graphics/SVG/SVG-19990812.dtd">
<xsl:output method="xml" indent="yes" media-type="image/svg"/>
<xsl:template match="/">
<svg width = "3in" height="3in">
    <g style = "stroke: #000000"> 
        
        <line x1="0" x2="150" y1="150" y2="150"/>
        <line x1="0" x2="0" y1="0" y2="150"/>
        <text x="0" y="10">Revenue</text>
        <text x="150" y="165">Division</text>
        <xsl:for-each select="sales/division">
	    
	    
	    <xsl:variable name="pos"
	                  select="(position()*40)-30"/>
	    
	    <xsl:variable name="height"
	                  select="revenue*10"/>
	    
	    <rect x="{$pos}" y="{150-$height}"
                  width="20" height="{$height}"/>
	    
	    <text x="{$pos}" y="165">
	        <xsl:value-of select="@id"/>
	    </text> 
	    
	    <text x="{$pos}" y="{145-$height}">
	        <xsl:value-of select="revenue"/>
	    </text>
        </xsl:for-each>
    </g>
</svg>
</xsl:template>
</xsl:stylesheet>

SVG での出力は以下のようになる。

<svg width="3in" height="3in"
     xmlns="http://www.w3.org/Graphics/SVG/svg-19990412.dtd">
    <g style="stroke: #000000">
	<line x1="0" x2="150" y1="150" y2="150"/>
	<line x1="0" x2="0" y1="0" y2="150"/>
	<text x="0" y="10">Revenue</text>
	<text x="150" y="165">Division</text>
	<rect x="10" y="50" width="20" height="100"/>
	<text x="10" y="165">North</text>
	<text x="10" y="45">10</text>
	<rect x="50" y="110" width="20" height="40"/>
	<text x="50" y="165">South</text>
	<text x="50" y="105">4</text>
	<rect x="90" y="90" width="20" height="60"/>
	<text x="90" y="165">West</text>
	<text x="90" y="85">6</text>
    </g>
</svg>

以下は、XML の入力データを VRML 形式に変換するスタイルシートである。

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

<xsl:output method="text" encoding="UTF-8" media-type="model/vrml"/>  
        <xsl:template match="/">#VRML V2.0 utf8 
 
# externproto definition of a single bar element 
EXTERNPROTO bar [ 
  field SFInt32 x  
  field SFInt32 y  
  field SFInt32 z  
  field SFString name  
  ] 
  "http://www.vrml.org/WorkingGroups/dbwork/barProto.wrl" 
 
# inline containing the graph axes 
Inline {  
        url "http://www.vrml.org/WorkingGroups/dbwork/barAxes.wrl" 
        } 
        
                <xsl:for-each select="sales/division">
bar {
        x <xsl:value-of select="revenue"/>
        y <xsl:value-of select="growth"/>
        z <xsl:value-of select="bonus"/>
        name "<xsl:value-of select="@id"/>" 
        }
                </xsl:for-each>
        
        </xsl:template> 
 
</xsl:stylesheet>

VRML での出力は以下のようになる。

#VRML V2.0 utf8 
 
# externproto definition of a single bar element 
EXTERNPROTO bar [ 
  field SFInt32 x  
  field SFInt32 y  
  field SFInt32 z  
  field SFString name  
  ] 
  "http://www.vrml.org/WorkingGroups/dbwork/barProto.wrl" 
 
# inline containing the graph axes 
Inline {  
        url "http://www.vrml.org/WorkingGroups/dbwork/barAxes.wrl" 
        } 
        
                
bar {
        x 10
        y 9
        z 7
        name "North" 
        }
                
bar {
        x 4
        y 3
        z 4
        name "South" 
        }
                
bar {
        x 6
        y -1.5
        z 2
        name "West" 
        }

E 謝辞 (規定外)

本稿の作成には、以下の方々にご協力いただいた。

この仕様は、W3C の XSL 作業グループ (WG) が策定して公開を承認した。WG による本仕様の承認は、WG の全委員が承認決議において賛成投票をしたことを意味するわけではない。XSL WG の現在の委員を以下に示す。

Sharon Adler、IBM (Co-Chair) ; Anders Berglund、IBM ; Perin Blanchard、Novell ; Scott Boag、Lotus ; Larry Cable、Sun ; Jeff Caruso、Bitstream ; James Clark ; Peter Danielsen、Bell Labs ; Don Day、IBM ; Stephen Deach、Adobe ; Dwayne Dicks、SoftQuad ; Andrew Greene、Bitstream ; Paul Grosso、Arbortext ; Eduardo Gutentag、Sun ; Juliane Harbarth、Software AG ; Mickey Kimchi、Enigma ; Chris Lilley、W3C ; Chris Maden、Exemplary Technologies ; Jonathan Marsh、Microsoft ; Alex Milowski、Lexica ; Steve Muench、Oracle ; Scott Parnell、Xerox ; Vincent Quint、W3C ; Dan Rapp、Novell ; Gregg Reynolds、Datalogics ; Jonathan Robie、Software AG ; Mark Scardina、Oracle ; Henry Thompson、University of Edinburgh ; Philip Wadler、Bell Labs ; Norman Walsh、Arbortext ; Sanjiva Weerawarana、IBM ; Steve Zilles、Adobe (Co-Chair)

F 勧告案からの変更点 (規定外)

勧告案 (Proposed Recommendation) からの変更点を以下に示す。

G XSLT の今後のバージョンについて検討中の機能 (規定外)

XSLT 1.0 以降のバージョンに向けて、以下の機能を検討している。