標準情報(TR)    TR X 0048:2001


XSL変換(XSLT) 1.0

XSL Transformations (XSLT) Version 1.0



序文

この標準情報(TR)は, 1999年11月にWorld Wide Web Consortium(W3C)から公表されたXSL Transformations (XSLT) Version 1.0勧告を翻訳し, 技術的内容を変更することなく作成した標準情報(TR)(タイプU)である。



1 導入

1.0 適用範囲

この規定は, XML文書を他のXML文書に変換するための言語であるXSLTの構文及びセマンティクスを定義する。

XSLTは,XML用のスタイルシート言語であるXSLの部分としての使用のために設計されている。XSLTに加えて,XSLは, フォーマット化指定のためのXML語い(彙)を含む。XSLは,フォーマット化語い(彙)を使用する別のXML文書に文書を変換する方法を記述するためにXSLTを使用することによって,XML文書のスタイルを指定する。

XSLTは,XSLとは独立に使用する設計もなされている。しかし,XSLTは,完全に一般目的のXML変換言語として意図されたものではなく, その設計の主目的は,XSLTをXSLの部分として使用する場合に必要となる変換にある。

1.1 概要

この標準情報(TR)は,XSLT言語の構文及びセマンティクスを定義する。XSLT言語の変換は, XML勧告の名前空間[XML Names]に適合する整形式のXML文書[XML]として表わされ,それは,XSLTが定義する要素もXSLTが定義しない要素も含んでよい。XSLT定義の要素は,固有のXML名前空間に属することによって識別され([2.1 XSLT名前空間]を参照), この標準情報(TR)では,これをXSLT名前空間と呼ぶ。したがって,この標準情報(TR)は,XSLT名前空間の構文及びセマンティクスを定義する。

XSLTで表される変換は,ソース木を結果木に変換するための規則を記述する。パタンをテンプレートに関連付けることによって,変換を達成する。パタンは, ソース木の要素と一致される。テンプレートはインスタンス化されて,結果木の部分を生成する。結果木は, ソース木から分離している。結果木の構造は, ソース木の構造とは全く異なり得る。結果木を構築する際には,ソース木からの要素をフィルタリングしたり,再順序化したりでき,任意の構造を追加することもできる。

XSLTで表される変換をスタイルシートと呼ぶ。これは,XSLTをXSLフォーマット化語い(彙)に変換する際に,その変換がスタイルシートとして機能することによる。

この標準情報(TR)は,XSLTスタイルシートがXML文書にどのように関連付けられるかは指定しない。XSLプロセサが[XML スタイルシート]で記述される機構をサポートすることを推奨する。この機構又はその他の機構が複数のXSLTスタイルシートの列を提供し,一つのXML文書に同時に適用される場合, その効果は,その列の各メンバを順にインポートする単一のスタイルシートを適用する場合と同じであることが望ましい([2.6.2 スタイルシートのインポート]を参照)。

スタイルシートは, テンプレート規則の集合を含む。テンプレート規則は, 次の二つの部分から成る。一つはソース木のノードに一致されるパタンであり,もう一つはインスタンス化できて,結果木の部分を形成するテンプレートとする。これによって,スタイルシートを類似のソース木構造をもつ文書の広いクラスに適用可能にする。

テンプレートは, 特定のソース要素に関してインスタンス化され,結果木の部分を生成する。テンプレートは, リテラル結果要素の構造を指定する要素を含むことができる。テンプレートは,結果木素片を生成するための命令であるXSLT名前空間からの要素も含むことができる。テンプレートがインスタンス化されると,各命令が実行され,それが生成する結果木素片によって置換される。命令は子孫ソース要素を選択し,処理することができる。 子孫要素の処理は,適用可能なテンプレート規則を見つけて,そのテンプレートをインスタンス化することによって結果木素片を生成する。要素は,命令の実行によって選択されたときだけに処理されることに注意すること。結果木は,根ノードに関するテンプレート規則を見つけて,そのテンプレートをインスタンス化することによって構成される。

適用可能なテンプレート規則を見つける処理において,複数のテンプレート規則が, 与えられた要素に一致するパタンをもってもよい。しかし,一つだけのテンプレート規則が適用される。適用するテンプレート規則を決定する方法は,[5.5 テンプレート規則の競合解決]に示す。

テンプレートは一つだけでかなりの能力をもつ。それは, 任意の複雑さをもつ構造を生成でき,ソース木の任意の位置から文字列の値を引き出すことができ,ソース木における要素の出現に応じて繰り返される構造を生成できる。 結果木の構造がソース木の構造とは独立である単純な変換については,スタイルシートは, 単一のテンプレートだけから構成されることも可能であり,それは,完全な結果木のためのテンプレートとして機能する。データを表現するXML文書の変換は,この種のものであることが多い([D.2 データの例]を参照)。 XSLTは,これらのスタイルシートに単純化した構文を適用することを可能にする( [2.3 スタイルシートとしてのリテラル結果要素]を参照)。

テンプレートは,インスタンス化されると,常に現ノード及び現ノードリストに関してインスタンス化される。現ノードは, 常に現ノードリストのメンバである。XSLTの多くのオペレーションは, 現ノードに対応する。わずかな命令だけが, 現ノードリスト又は現ノードを変更する([5 テンプレート規則]及び[8 繰返し]を参照)。これらの命令の一つをインスタンス化する間に,現ノードリストはノードの新リストに変わり,この新リストの各メンバが順に現ノードになる。命令のインスタンス化の完了後は,現ノード及び現ノードリストは,命令がインスタンス化される前の状態に戻る。

XSLTは,[XPath]で定義された式言語を利用して,処理, 条件付き処理及びテキスト生成のための要素の選択を行う。

XSLTは, 言語を拡張するために二つの"フック"を提供する。つまり, テンプレートで使用する命令要素の集合を拡張するためのフック,及び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の版を示してはいない。使用するXSLTの版は, 属性によって指定する([2.2 スタイルシート要素]及び[2.3 スタイルシートとしてのリテラル結果要素]を参照)。

XSLTプロセサは,この名前空間から要素及び属性を認識するために, XML名前空間の機構[XML Names]を使用しなければならない。XSLT名前空間からの要素は,ソース文書の中ではなく,スタイルシートの中だけで認識される。XSLT定義の要素の完全リストは, [B 要素構文のまとめ]の中で指定される。ベンダは, 追加の要素又は属性でXSLT名前空間を拡張してはならない。代わりに,どんな拡張も, 別の名前空間の中になければならない。追加の命令要素に使用されるどの名前空間も,[14.1 拡張要素 ]の中で指定される拡張要素の機構によって識別されなければならない。

この標準情報(TR)は,XSLT名前空間の要素を参照するために, 接頭辞xsl:を使用する。しかし,XSLTスタイルシートは,接頭辞をXSLT名前空間のURIに結合する名前空間宣言があれば,どんな接頭辞も自由に使える。

XSLT名前空間の要素は,属性の拡張名が非nullの名前空間URIをもてば,XSLT名前空間からでないどんな属性をもってもよい。これらの属性の存在は,この文書の中で定義するXSLTの要素及び関数の振舞いを変更してはならない。したがって,XSLTプロセサは,これらの属性をいつでも自由に無視でき,それが名前空間URIを認識しなければ,エラーを与えることなく,それらの属性を無視しなければならない。それらの属性は,例えば,一意の識別子,最適化ヒント又はドキュメンテーションを提供できる。

XSLT名前空間からの要素が, この文書の中で要素に関して定義される属性以外の, null名前空間URIをもつ拡張名のついた属性(つまり, 接頭辞なしの名前をもつ属性)をもつことは,エラーとする。

備考 XSLTの要素,属性及び関数の名前に使用する規約は,次のとおりとする。つまり, 名前は, すべて小文字であり,ハイフンを用いて語を分離し,XML又はHTMLなどの関連する言語の構文の中に既に現れている場合だけ,短縮形を使用する。

2.2 スタイルシート要素

<xsl:stylesheet
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  <!-- Content: (xsl:import*, top-level-elements) -->
</xsl:stylesheet>

<xsl:transform
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  <!-- Content: (xsl:import*, top-level-elements) -->
</xsl:transform>

スタイルシートは,XML文書におけるxsl:stylesheet要素によって表現される。 xsl:transformは, xsl:stylesheetの同義語として使用できる。

xsl:stylesheet要素は,スタイルシートが要求するXSLTの版を示すために, version属性をもたなければならない。XSLTのこの版に関しては, その値は, 1.0とする。値が1.0に等しくないときは,前方互換処理モードが可能になる([2.5 前方互換処理]を参照)。

xsl:stylesheet要素は, 次の型の要素を含んでよい。

xsl:stylesheet要素の子として出現する要素を, 最上位要素と呼ぶ。

この例は,スタイルシートの構造を示す。省略記号(...)は, どこで属性値又は内容が省略されているかを示す。この例は,使用できる要素の各型の一つを示すが,スタイルシートは, これらの要素をそれぞれを全く含まなくてもよく,幾つ含んでもよい。

<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の要素及び関数の振舞いを変更してはならない。例えば,これらの最上位要素が,xsl:apply-templatesが競合を解決するために異なる規則を使用することを指定することは許可されない。したがって,XSLTプロセサは, 常にこれらの最上位要素を自由に無視でき,名前空間URIを認識しなければ,エラーを与えることなしに最上位要素を無視しなければならない。これらの要素は, 次に例示する情報を与えることができる。

2.3 スタイルシートとしてのリテラル結果要素

根ノードに関して単一のテンプレートだけで構成されるスタイルシートには,簡素化した構文を使用できる。スタイルシートは,リテラル結果要素だけで構成してよい( [7.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>

スタイルシートの文書要素であるリテラル結果要素は,xsl:version属性をもたなければならない。この属性は,スタイルシートが要求するXSLTの版を示す。XSLTのこの版については,その値は1.0とする。値は, 数値でなければならない。他のリテラル結果要素も, xsl:version属性をもってよい。 xsl:version属性が1.0に等しくないとき,前方互換処理モードが可能になる([2.5 前方互換処理]を参照。)。

スタイルシートとして使用されるときに可能なリテラル結果要素の内容は,スタイルシートの中でそれが現れるときからの違いはない。したがって,スタイルシートとして使用されるリテラル結果要素は,最上位要素を含むことができない。

XML文書がXSLTスタイルシートとしてXSLTプロセサによって処理されなければならないということを, システムが認識できるただ一つの方法は,状況によっては, XML文書そのものを検査することになる。簡素化した構文を使用することは,この処理をもっと困難にする。

備考 例えば, 別のXML言語(AXL)は, XML文書がAXLプロセサによって処理されなければならないAXL文書であったことを示すために, 文書要素にaxl:versionをも用いるかも知れない。文書がaxl:version属性及びxsl:version属性の両方をもてば,文書をXSLTプロセサによって処理するのがよいか,AXLプロセサによって処理するのがよいかは明確でない。

そのため, この状況で使用できるXSLTスタイルシートには,簡素化した構文を使用することは望ましくない。例えば,MIMEメディア型を使用してメッセージの処理方法を決定する受信者に,text/xml又はapplication/xmlのMIMEメディア型をもつメッセージとしてXSLTスタイルシートを送るとき,この状況が生じ得る。

2.4 修飾された名前

内部XSLTオブジェクトの名前,特に名前付きテンプレート([6 名前付きテンプレート]を参照。), モード ([5.7 モード]を参照。), 属性集合([7.1.4 名前付き属性集合]を参照。), キー([12.2 キー]を参照。), 10進フォーマット([12.3 数字のフォーマット化]を参照。), 変数又はパラメタ([11 変数及びパラメタ]を参照。)は,QNameとして指定される。 接頭辞があると,名前が現れる属性に実際に名前空間宣言を使用して,接頭辞がURI参照に拡張される。拡張名は,名前の局所部分とたぶんnullのURI参照とから構成され,オブジェクトの名前として使用される。デフォルト名前空間は,接頭辞なしの名前には使用されない

2.5 前方互換処理

要素が, version属性が1.0に等しくないxsl:stylesheet要素であるか, 値が1.0に等しくないxsl:version属性をもつリテラル結果要素であるか,xsl:version属性をもたず, 簡素化された構文を用いるスタイルシートの文書要素であるリテラル結果要素であるか,のどれかである場合([2.3 スタイルシートとしてのリテラル結果要素]を参照。),要素は,要素自体,要素の属性,要素の子孫及びそれらの属性に関して前方互換モードを可能にする。値が1.0に等しいxsl:version属性をもつリテラル結果要素は,それ自体,その属性,その子孫及びそれらの属性に関して前方互換モードを不可能にする。

要素が前方互換モードで処理される場合, 次に示すとおりとなる。

したがって,この規定で定義されないXSLT名前空間からの要素をスタイルシートが含んでも,どんなXSLT 1.0プロセサも,次のスタイルシートをエラーなしに処理できなければならない。

<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を実装しているXSLTプロセサが黙って最上位要素を無視しないことを確実にするために, terminate="yes"をもつxsl:message要素([13 メッセージ]を参照。)を用いることができる。 次に, それを例示する。
<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プロセサは, 式でのエラーから次のとおり回復しなければならない。

2.6 スタイルシートの結合

XSLTには,スタイルシートを結合する機構が二つ存在する。

2.6.1 スタイルシートの取込み

<!-- Category: top-level-element -->
<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 の両方を取り込む場合,A は,間接的に D に2度取り込まれる。BC 及び D のすべてを独立したスタイルシートとして使用する場合,A の取込み以外の B のすべてを別のスタイルシート B' に分離し,B を変更して B' 及び A の取込みだけを含むものとし,C についても同様の処理を行って,D を,AB' 及び 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要素の子供すべてに優先しなければならない。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要素を含むスタイルシートの処理中に出現したxsl:stylesheet要素は,インポート木を形成するものとして取り扱われる。インポート木では,各xsl:stylesheet要素は,それが含む各xsl:import要素に対して,一つのインポートの子をもつ。xsl:include要素は,いずれも,インポート木を構成する前に解決される。インポート木の後順たどり(すなわち,あるxsl:stylesheet要素をその要素のインポートの子よりも後に訪れるというインポート木のたどり)において,あるxsl:stylesheet要素がそのインポート木における他のxsl:stylesheet要素の前に出現した場合,そのxsl:stylesheet要素は,他のxsl:stylesheet要素よりも低いインポート優先順位をもつと定義される。各々の定義及びテンプレート規則は,その定義及びテンプレート規則を含むxsl:stylesheet要素が決定するインポート優先順位をもつ。

例えば,次の例を考える

このときインポートの優先順位は,低い方から,DBEC 及び A となる。

備考 xsl:import要素はいかなる定義又はテンプレート規則より前に出現することを要求されるので,xsl:import要素に出会った時点でインポートされたスタイルシートを処理する実装は,インポート優先順位が高くなる順に定義及びテンプレート規則に出会うことになる。

一般に,インポート優先順位のより高い定義又はテンプレート規則は,優先順位のより低い定義又はテンプレート規則に優先する。これは,各種の定義及びテンプレート規則に対して詳細に定義される。

スタイルシートがそれ自体を直接的又は間接的にインポートする場合は,エラーとする。これとは別に,特定のURIをもつスタイルシートが複数の場所でインポートされる場合は,特別な扱いをしない。インポート木は,インポートされる場所ごとに別々のxsl:stylesheetをもつことになる。

備考 xsl:apply-importsが使用される場合([5.6 テンプレート規則の上書き]を参照),その振る舞いは,インポート優先順位が最も高い場所でだけスタイルシートがインポートされた場合に,異なってもよい。

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

通常,XSLTスタイルシートは,文書要素としてxsl:stylesheet要素をもつ完全なXML文書とする。しかし,XSLTスタイルシートは,他の資源に埋め込まれることがあってもよい。次の二つの埋込み形式が,可能となる。

2番目の埋込み形式を容易にするために,xsl:stylesheet要素は,一意な識別子を指定するID属性をもつことができる。

備考 このような属性をXPathのid関数で使用するためには,この属性がIDであるものとして実際にDTDで宣言されなければならない。

xml-stylesheet処理命令[XML Stylesheet]を使用して,文書に独自のスタイルシートを含める方法を次の例で示す。URI参照は,素片識別子をもつ相対URIを使用して,xsl:stylesheet要素を位置決めする。

<?xml-stylesheet type="text/xml" href="#style1"?>
<!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">
  <!-- ignore -->
</xsl:template>
</xsl:stylesheet>
</head>
<body>
<para id="foo">
...
</para>
</body>
</doc>
備考 スタイルシートが適用される文書に埋め込まれるか,又は埋め込まれたスタイルシートに取り込まれたりインポートされたりしてよい場合,それらスタイルシートは,xsl:stylesheet要素を無視することを指定するテンプレート規則を含む必要がある。

3. データモデル

XSLTが使用するデータモデルは,XPathが使用するデータモデルに3.で示すものを付加したものと同じとする。XSLTは,同じデータモデルを使用している,ソース文書,結果文書及びスタイルシート文書に関して処理を行う。同じ木をもつ二つのXML文書は,いずれも,XSLTによって同じに取り扱われる。

スタイルシートにおける処理命令及びコメントは無視される。すなわち,スタイルシートは,そのスタイルシートを表現する木に処理命令ノードもコメントノードも含まれないものとして取り扱われる。

3.1 根ノードの子供

根ノードの子供に関する通常の制限は,結果木では緩和される。結果木は,ノードの列を,一つの要素ノードに対して可能な子供としてもってよい。特に,結果木は,テキストノードの子供及びどのような数の要素ノードの子供をもってもよい。XML出力メソッド([16. 出力]を参照)を使用して書き出す場合,結果木が整形式のXML文書でない可能性もある。しかし,結果木は,常に整形式の外部一般解析実体となる。

整形式のXML文書を構文解析することによってソース木が生成される場合,ソース木の根ノードは,テキストノードの子供をもたず,要素の子をちょうど一つだけもつという通常の制限を自動的に満たすことになる。他の方法,例えば,DOMを使用して,ソース木が生成される場合には,通常の制約は,結果木の場合と同じようにソース木で緩和される。

3.2 基底URI

どのノードにも基底URIと呼ばれる関連するURIが存在する。これは,相対URIを表現する属性値を絶対URIに変換するために使用される。要素又は処理命令が外部実体で出現する場合,その要素又は処理命令の基底URIは,その外部実体のURIとする。そうでない場合は,基底URIは,その文書の基底URIとする。文書ノードの基底URIは,その文書実体のURIとする。テキストノード,コメントノード,属性ノード又は名前空間ノードに対する基底URIは,そのノードの親の基底URIとする。

3.3 解析対象外実体

根ノードには,文書のDTDで宣言された解析対象外実体の各々に対してURIを与える対応付けが存在する。このURIは,実体宣言で指定されたシステム識別子及び公開識別子から生成される。XSLTプロセサは,公開識別子を使用して,システム識別子で指定されたURIの代わりに,実体に対応するURIを生成してもよい。XSLTプロセサが公開識別子を使用してURIを生成しない場合は,システム識別子を使用しなければならない。すなわち,システム識別子が相対URIである場合は,基底URIとしての実体宣言を含む資源のURIを使用して,絶対URIへと解決しなければならない[RFC2396]

3.4 空白の削除

ソース文書又はスタイルシート文書の木が構成された後で,XSLTが他の処理を行う前に,削除されるテキストノードもある。テキストノードが空白文字だけを含む場合以外は,テキストノードは削除されない。テキストノードを削除することによって,木からテキストノードが取り除かれる。削除処理は,空白を保存しなければならない要素名(以降、空白保存要素名)の集合を入力として取る。削除処理は,スタイルシートにもソース文書にも適用されるが,空白保存要素名の集合は,スタイルシート及びソース文書に対して異なって決定される。

次のいずれかが適用される場合には,テキストノードは保存される。

それ以外の場合は,テキストノードは削除される。

xml:space属性は,木から削除されない。

備考 このことは,xml:space属性がリテラル結果要素に指定されている場合には,それが結果に含まれることを意味する。

スタイルシートの場合,空白保存要素名の集合は,xsl:textだけから構成される。

<!-- Category: top-level-element -->
<xsl:strip-space
  elements = tokens />

<!-- Category: top-level-element -->
<xsl:preserve-space
  elements = tokens />

ソース文書の場合,空白保存要素名の集合は,xsl:strip-space及びxsl:preserve-space最上位要素によって指定される。これらの要素には,それぞれelements属性が存在し,その値は空白で区切られたNameTestのリストとする。最初の段階では,空白保存要素名の集合はすべての要素名を含む。要素名がxsl:strip-space要素のNameTestに一致する場合,その要素名は,空白保存要素名の集合から取り除かれる。要素名がxsl:preserve-space要素のNameTestに一致する場合,その要素名は,空白保存要素名の集合に追加される。NameTestXPathのノードテストとしての要素に対して真の場合に限り,要素は,NameTestに一致する。xsl:strip-space要素への一致とxsl:preserve-space要素への一致との間で競合が発生した場合は,テンプレート規則間の競合と同じ方法で解決される([5.5 テンプレート規則の競合解決]を参照)。そこで,特定の要素名に適用できる一致は,次のとおりに決定される。

二つ以上の一致が残る場合はエラーとする。XSLTプロセサは,このエラーを通知してもよい。エラーを通知しない場合は,残った一致の中から,スタイルシートで最後に出現するものを選択することによって,エラーから回復しなければならない。

4 式

XSLTは,XPath[XPath]が定義する式言語を使用する。XSLTでは,次を含む様々な目的に式を使用する。

は,XPath生成規則のExprに一致しなければならない。

式は,XSLT定義の要素に関する特定の属性値として属性値テンプレートに波括弧で囲まれた形式で出現する。

XSLTでは,最も外側の式,すなわち,他の式の一部ではない式が,その文脈を取得する。その方法を次に示す。

5 テンプレート規則

5.1 処理モデル

ソースノードのリストを処理すると,結果木素片が生成される。結果木は,根ノードだけを含むリストを処理することによって構成される。ソースノードのリストは,リストの各メンバを順に処理することで生成される結果木構造を追加することによって処理される。ノードは,そのノードと一致するパタンをもつすべてのテンプレート規則を見い出し,その中で最適なものを選択することによって,処理される。選択された規則のテンプレートは,現ノードとしてのノード及び現ノードリストとしてのソースノードのリストを用いてインスタンス化される。テンプレートは,通常,処理対象となるソースノードの付加的なリストを選択する命令を含んでいる。一致化,インスタンス化及び選択という過程は,新しいソースノードが処理のために選択されなくなるまで再帰的に繰り返される。

実装は,この処理モデルを使用して処理された場合と同じ結果となる方法であれば,いかなる方法でも,ソース文書を自由に処理できる。

5.2 パタン

テンプレート規則は,パタンを使用することで,適用されるノードを識別する。テンプレート規則で使用されるのと同様に,パタンは,番号付け([7.7 番号付け]を参照)及びキーの宣言([12.2 キー]を参照)のために使用される。パタンは,ノードに関する条件の集合を指定する。条件を満たすノードは,パタンに一致する。条件を満たさないノードは,パタンに一致しない。パタンの構文は,式の構文の部分集合とする。特に,一定の制限を満たす位置決めバスは,パタンとして使用できる。パタンでもある式は,常にノード集合の型のオブジェクトと評価される。パタンを幾つかの可能な文脈に関して式として評価した結果のメンバにノードがなる場合,そのノードはそのパタンに一致する。ここで,可能な文脈とは,文脈のノードが一致判定の対象となっているノードであるか,又はその先祖のノードである文脈のこととする。

パタンの例を次に示す。

パタンは,Patternの文法と一致しなければならない。Patternは,|で区切られた位置決めパスのパタンの集合とする。位置決めパスのパタンとは,その段階がすべてchild軸又はattribute軸だけを使用する位置決めパスのこととする。パタンは,descendant-or-self軸を使用してはならないが,演算子/と同様に演算子//を使用してもよい。位置決めパスのパタンを,リテラル引数をもつid関数又はkey関数の呼出しで始めることもできる。パタン内の述語には,位置決めパス内の述語と同様に任意の式を使用できる。

Patterns
[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要素でも,これは合致する。

パタンのセマンティクスは,式の評価に関して間接的に規定されるが,式の評価に関して考えることなく直接的にパタンの意味を理解するのは容易である。パタンにおいて,|は選択肢の存在を示している。|で区切られた選択肢を一つ以上もつパタンは,その選択肢のいずれかが一致すると,パタンとして一致する。/又は//で区切られたStepPatternの列から成るパタンは,右から左に向かって一致判定される。このパタンが一致するのは,最も右のStepPatternが一致し,適切な要素がパタンの残りに一致する場合とする。区切り子が/である場合は,親だけが適切な要素となる。区切り子が//である場合は,どの先祖であっても適切な要素となる。子の軸を使用するStepPatternは,NodeTestがノードに対して真であって,ノードが属性ノードではない場合に一致する。属性の軸を使用するStepPatternは,NodeTestがノードに対して真であって,ノードが属性ノードである場合に一致する。[]が存在する場合には,StepPatternにおける最初のPredicateExprは,文脈ノードとして一致判定されるノード,及びその文脈ノードの兄弟であって文脈ノードリストとしてNodeTestに一致するものと一緒に評価される。ただし,一致判定されるノードは属性ノードではなく,その場合,文脈ノードリストは,一致判定される属性と同じ親をもちNameTestに一致するすべての属性とする。

次に例を示す。

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

この例は,次のすべての場合が真のときに限り,ノードと一致する。

5.3 テンプレート規則の定義

<!-- Category: top-level-element -->
<xsl:template
  match = pattern
  name = qname
  priority = number
  mode = qname>
  <!-- Content: (xsl:param*, template) -->
</xsl:template>

テンプレート規則は,xsl:template要素を用いて指定される。 match属性は,ソースノード,又はその規則が適用するノードを識別する Patternとする。 xsl:template要素がname属性をもたなければ, match属性が,要求される( [6 名前付きテンプレート]を参照)。match属性の値がVariableReferenceを 含むことは, エラーとする。xsl:template要素の内容は,テンプレート規則が適用されるときインスタンス化されるテンプレートとする。

例えば, XML文書が次を含むとする。

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

次のテンプレート規則は, emph要素に一致し, boldfont-weight特性をもつ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/Formatfo:接頭辞を使用する。この名前空間は, [XSL]で定義されるフォーマット化オブジェクトの名前空間とする。

5.4に示すとおり,xsl:apply-templates要素は, ソース要素の子供を 再帰的に処理する。

5.4 テンプレート規則の適用

<!-- Category: instruction -->
<xsl:apply-templates
  select = node-set-expression
  mode = qname>
  <!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>

次の例は,chapter要素に関してブロックを生成し, その直接の子供を処理する。

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

select属性が存在しないとき, xsl:apply-templates命令は,テキストノードを含む現ノードのすべての子供を処理する。しかし,[3.4 空白の削除]で指定されるとおり,削除されたテキストノードは処理されない。 空白ノードの削除が要素に関して不可能であったとき,要素の内容にあるすべての空白はテキストとして処理され,したがって,子要素間の空白は,position関数によって返される, 子要素の位置の決定において意味をもつ。

select属性は, すべての子供を処理する代わりに,式が選択するノードを処理するために, 使用できる。select属性の値は, とする。式は, ノード集合に評価される。選択されたノード集合は,ソートの規定が存在しなければ([10 ソート]を参照), 文書順に処理される。 次の例は,author-groupの子供であるauthorをすべてを処理する。

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

次の例は, author-groupの子供であるauthorgiven-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要素は, 簡単な再順序付けをするために, 単一のテンプレート内で使用できる。次の例は,二つのHTMLの表を生成する。最初の表は国内販売が記入され,二つ目の表は海外販売が記入される。

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="sales/domestic"/>
  </table>
  <table>
    <xsl:apply-templates select="sales/foreign"/>
  </table>
</xsl:template>
備考1 二つの一致する子孫があり,その一方が他方の子孫であることもある。この場合も特別には取り扱われない。どちらの子孫も通常どおり処理される。例えば,次のソース文書を考える。
<doc><div><div></div></div></doc>
ここで,
<xsl:template match="doc">
  <xsl:apply-templates select=".//div"/>
</xsl:template>
という規則は,外側のdiv要素も内側のdiv要素も処理する。
備考2 通常, xsl:apply-templatesは, 現ノードの子孫であるノードだけを処理するために, 使用される。xsl:apply-templatesをこのとおりに使用すると,非終端処理ループを生じさせることはない。しかし,xsl:apply-templatesを,現ノードの子孫ではない要素を処理するために使用すると,非終端ループを発生する可能性がある。次に例を示す。
<xsl:template match="foo">
  <xsl:apply-templates select="."/>
</xsl:template>
実装がこのループを検知できることがあるかもしれないが,実装が検知できない非終端ループにスタイルシートがはいる可能性がある。 これは,サービスセキュリティリスクの否定を示すものかもしれない。

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

一つのソースノードは, 複数のテンプレート規則に一致できる。 使用するテンプレート規則の決定方法を次に示す

  1. 最初に,最高のインポート優先順位をもつ一致するテンプレート規則(単数又は複数)より低いインポート優先順位をもつ, すべての一致するテンプレート規則を考慮から除外する。

  2. 次に, 最高の優先度をもつ一致するテンプレート規則(単数又は複数)より低い優先度をもつすべての一致するテンプレート規則を考慮から除外する。 テンプレート規則の優先度は,テンプレート規則のpriority属性によって指定される。この値は,オプションとして先頭にマイナス記号(-)が付く生成規則Numberに一致する, 正又は負の実数でなければならない。 デフォルト優先度は, 次のとおり計算される。

    したがって, 最も普通の種類のパタン(特定の型及び特定の拡張名をもつノードについてテストするパタン)は, 優先度0をもつ。次に固有性の低い種類のパタン(特定の型及び特定の名前空間URIの拡張名をもつノードについてテストするパタン)は, 優先度-0.25をもつ。それより固有性の低いパタン(特定の型をもつノードをテストするだけのパタン)は, 優先度-0.5をもつ。最も普通の種類のパタンよりも固有性の高いパタンは, 優先度0.5をもつ。

この処理が, 複数の一致するテンプレート規則を残すことは, エラーとする。 XSLTプロセサは, エラーを通知してもよい。エラーを通知しないとき,XSLTプロセサは, 残った一致するテンプレート規則の中から,スタイルシートの中に最後に現れる一つを選択することによって,回復しなければならない。

5.6 テンプレート規則の上書き

<!-- Category: instruction -->
<xsl:apply-imports />

インポートされるスタイルシートにおいてテンプレート規則を上書きするために使用されるテンプレート規則([5.5 テンプレート規則の競合解決]を参照)は,上書きされたテンプレート規則を呼び出すために, xsl:apply-imports要素を使用できる。

スタイルシートの処理のどの点でも,現テンプレート規則が存在する。パタンを一致化することによってテンプレート規則が選択されるときは常に,そのテンプレート規則が, 規則のテンプレートのインスタンス化に関する現テンプレート規則となる。 xsl:for-each要素をインスタンス化すると, 現テンプレート規則は, xsl:for-each要素の内容のインスタンス化に関してnullとなる。

xsl:apply-importsは,現テンプレート規則を含むスタイルシート要素の中にインポートされたテンプレート規則だけを使用して,現ノードを処理する。 ノードは, 現テンプレート規則のモードで処理される。現テンプレート規則がnullであるとき,xsl:apply-importsがインスタンス化されるのはエラーとする。

例えば, スタイルシートdoc.xslexample要素に関する テンプレート規則を含むとする。

<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:template及びxsl:apply-templatesは, どちらもオプションのmode属性をもつ。mode属性の値は, QNameであり, それは[2.4 修飾された名前]で記述されるとおりに拡張される。 xsl:templatematch属性をもたないとき, それはmode属性をもってはならない。 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 名前付きテンプレート

<!-- Category: instruction -->
<xsl:call-template
  name = qname>
  <!-- Content: xsl:with-param* -->
</xsl:call-template>

テンプレートは, 名前によって呼び出せる。name属性をもつxsl:template要素は, 名前付きテンプレートを指定する。 name属性の値は, QNameであり, それは[2.4 修飾された名前 ]で記述されるとおりに拡張される。xsl:template要素が name属性をもつとき,それはmatch属性をもってもよいが, 必ずしももつ必要はない。xsl:call-template要素は, 名前によってテンプレートを呼び出す。それは, 呼び出されるテンプレートを識別するname属性を必要とする。 xsl:apply-templatesとは異なり, xsl:call-templateは, 現ノード又は現ノードリストを変更しない。

xsl:template要素のmatch属性, mode属性 及びpriority属性は, テンプレートがxsl:call-template要素によって呼び出されるかどうかに影響を与えない。 同様に, xsl:template要素のname属性は, xsl:apply-templates要素によってテンプレートが呼び出されるかどうかに影響を与えない。

スタイルシートが, 同じ名前及び同じインポート優先順位をもつ複数のテンプレートを含むとき, それはエラーとなる。

7 結果木の生成

結果木の中にノードを直接生成する命令を, 7に示す。

7.1 要素及び属性の生成

7.1.1 リテラル結果要素

テンプレートにおいては, XSLT名前空間に属さず, 拡張要素([14.1 拡張要素]を参照)ではないスタイルシートの要素は,インスタンス化されて,同じ拡張名をもつ要素ノードを生成する。要素の内容は, テンプレートであり,それはインスタンス化されて,生成された要素ノードの内容を与える。生成された要素ノードは, スタイルシート木の要素ノード上に存在した属性ノードで,XSLT名前空間において 名前をもつ属性以外の属性ノードをもつことになる。

生成された要素ノードは,スタイルシート木の要素ノード上に存在した名前空間ノードのコピーももつことになる。ただし,文字列の値が, XSLT名前空間URI(http://www.w3.org/1999/XSL/Transform), 拡張名前空間として宣言された名前空間URI([14.1 拡張要素 ]を参照), 又は排除される名前空間として指定される名前空間URI である名前空間は除く。 名前空間URIは,xsl:stylesheet要素のexclude-result-prefixes属性又はリテラル結果要素のxsl:exclude-result-prefixes属性を使用することによって,排除される名前空間として指定される。 これらの属性の値はどちらも,名前空間接頭辞の空白で区切ったリストとする。 各接頭辞に限定される名前空間は,排除される名前空間として指定される。 exclude-result-prefixes属性又はxsl:exclude-result-prefixes属性をもつ要素に,接頭辞に限定される名前空間が存在しないときは, エラーとする。 (xmlnsによって宣言される)デフォルト名前空間は,名前空間の接頭辞のリストに#defaultを含むことによって,排除される名前空間として指定されてもよい。 排除される名前空間としての名前空間の指定は,exclude-result-prefixes属性又はxsl:exclude-result-prefixes属性をもつ要素を根とするスタイルシートの下位木の中で有効となる。 xsl:stylesheet要素を根とする下位木は,そのxsl:stylesheet要素の子供によってインポートされる又は含まれるどんなスタイルシートをも含まない。

備考 スタイルシートが, ソース木をアドレスするためだけに名前空間宣言を使用する場合,exclude-result-prefixes属性における接頭辞の指定は,結果木の不必要な名前空間宣言を回避することになる。

リテラル結果要素の属性値は,属性値テンプレートとして解釈される。このテンプレートは,波括弧({})の中にある式を含むことができる。

結果木において名前空間URIを指定するために用いられるスタイルシート木の名前空間URIを, リテラル名前空間URIと呼ぶ。 これは次に適用される。

<!-- Category: top-level-element -->
<xsl:namespace-alias
  stylesheet-prefix = prefix | "#default"
  result-prefix = prefix | "#default" />

スタイルシートは,ある名前空間URIが別の名前空間URIに関する別名であると宣言するために, xsl:namespace-alias要素を使用できる。リテラル名前空間URI が別の名前空間URIに関する別名になると宣言されたとき,結果木の名前空間URIは, リテラル名前空間URIそのものの代わりに,リテラル名前空間URIがその別名である名前空間URIとなる。 xsl:namespace-alias要素は, stylesheet-prefix属性によって指定される接頭辞に限定される名前空間URIが, result-prefix属性によって指定される接頭辞に限定される名前空間URIに関する別名であると宣言する。したがって, stylesheet-prefix属性は,スタイルシートに現れる名前空間URIを指定し,result-prefix属性は,結果木に現れる対応する名前空間URIを指定する。(xmlnsによって宣言される)デフォルト名前空間は,接頭辞の代わりに#defaultを使用して指定されてもよい。 名前空間URIが複数の異なる名前空間URIに関する別名になると宣言されると,最高のインポート優先順位をもつ宣言が使用される。この宣言が複数存在する場合は,エラーとする。 XSLTプロセサはエラーを通知してよい。エラーを通知しない場合は, 最高のインポート優先順位をもつ宣言の中から,スタイルシートの最後に現れるものを 選択することによって,エラーから回復しなければならない。

リテラル結果要素を使用して,要素,属性又はXSLT名前空間URIを使用する 名前空間ノードを生成する場合,スタイルシートは別名を使用しなければならない。 次にその例を示す。

<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による要素の生成

<!-- Category: instruction -->
<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:element>

xsl:element要素は, 計算された名前を用いて要素を生成することを可能にする。生成される要素の拡張名は,要求されるname属性及びオプションのnamespace属性によって指定される。 xsl:element要素の内容は,属性及び生成された要素の子供に関するテンプレートとする。

name属性は, 属性値テンプレートとして解釈される。属性値テンプレートをインスタンス化した結果としての文字列がQNameでない場合は, エラーとする。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合は,xsl:element要素をインスタンス化した結果を, どのような初期属性ノードをも除き, xsl:element要素の内容をインスタンス化することによって生成されるノードの列にすることによって, エラーから回復しなければならない。 namespace属性が存在しない場合,QNameは,どのようなデフォルト名前空間宣言をも含めて,実際にxsl:element要素に関する名前空間宣言を使用して, 拡張名に拡張される。

namespace属性が存在する場合には, それは, 属性値テンプレートとしても解釈される。属性値テンプレートをインスタンス化した結果から生じる文字列は,URI参照になることが望ましい。文字列が構文に合ったURI参照でなければ,エラーではない。 文字列が空のとき,要素の拡張名は, null名前空間URIをもつ。そうでないとき,文字列は, 生成される要素の拡張名の名前空間URIとして使用される。name属性が指定するQNameの局所部分は,生成される要素の拡張名の局所部分として使用される。

XSLTプロセサは,生成される要素をXMLとして出力するために使用される接頭辞を選択するとき,name属性で指定されるQNameの接頭辞を利用してもよい。 しかし, それらは必須ではない。

7.1.3 xsl:attributeによる属性の生成

<!-- Category: instruction -->
<xsl:attribute
  name = { qname }
  namespace = { uri-reference }>
  <!-- Content: template -->
</xsl:attribute>

xsl:attribute要素は, スタイルシートにおけるリテラル結果要素によって生成されようと,xsl:elementなどの命令によって生成されようと, 結果要素に属性を追加するために使用できる。生成される属性の拡張名は,要求されるname属性及びオプションのnamespace属性によって指定される。 xsl:attribute要素をインスタンス化することは,含まれる結果要素のノードに属性ノードを追加する。xsl:attribute要素の内容は,生成される属性の値に関するテンプレートとする。

name属性は,属性値テンプレートとして解釈される。属性値テンプレートをインスタンス化することの結果として得られる文字列がQNameではないか,文字列xmlnsになる場合は, エラーとする。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合は,結果木に属性を追加しないことによって, エラーから回復しなければならない。namespace属性が存在しない場合,QNameは, どのようなデフォルトの名前空間宣言をも含めないで, 実際にxsl:attribute要素に関する名前空間宣言を使用して,拡張名に拡張される。

namespace属性が存在する場合, それは, 属性値テンプレートとしても解釈される。それをインスタンス化した結果から生じる文字列は,URI参照になることが望ましい。文字列が構文に合ったURIでなければ,エラーではない。文字列が空のとき,属性の拡張名はnull名前空間URIをもつ。そうではない場合,文字列は,生成される属性の拡張名の名前空間URIとして使用される。 name属性が指定するQNameの局所部分は,生成される属性の拡張名の局所部分として使用される。

XSLTプロセサは,生成される属性をXMLとして出力するために使用される接頭辞を 選択する際に,name属性で指定されるQNameの接頭辞を利用してもよい。 しかし, これは必須ではなく,接頭辞がxmlnsであるときは, 利用してはならない。したがって,次の例はエラーではない。

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

しかし,出力される名前空間宣言になることはない。

要素に属性を追加することは,その要素のどんな既存の属性をも, 同一の拡張名で置き換える。

次はすべてエラーとする。

備考 xsl:attributeが改行のあるテキストノードを 含む場合,XML出力は文字参照を含まなければならない。次にそれを例示する。
<xsl:attribute name="a">x
y</xsl:attribute>
この記述は,次の出力を与える。
a="x&#xA;y"
(又は,同等のすべての文字参照を出力する結果となる。) XML出力は, 次のとおりではあり得ない。
a="x
y"
これは,XML1.0が, 属性値における改行文字はスペースに正規化されることを要求するが, 改行文字への文字参照は正規化されないことを要求することに基づく。 データモデルの属性値は,正規化後の属性値を表す。 木の属性値に現れる改行が,文字参照としてではなく改行文字として出力された場合, XMLの再構文解析によって生成される木の属性値は,改行ではなくスペースを含むことになる。これは,木が正しく出力されなかったことを意味する。

7.1.4 名前付き属性集合

<!-- Category: top-level-element -->
<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
  <!-- Content: xsl:attribute* -->
</xsl:attribute-set>

xsl:attribute-set要素は,名前付き属性集合を定義する。 name属性は,属性集合の名前を指定する。name属性の値は,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として指定され,それは, [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属性をもつ要素をインスタンス化するために使用される場合と同じ現ノード及び現ノードリストが使用される。 しかし,どの変数の結合が見えるかを決定するのは,use-attribute-sets属性又はxsl:use-attribute-sets属性をもつ要素のスタイルシートの位置ではなく,xsl:attribute要素のスタイルシートの位置となる([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>

同一の拡張名をもつ属性集合の複数定義は,併合される。 インポート優先順位が高い定義からの属性は,インポート優先順位がそれよりも低い定義からの属性に優先する。 同一の拡張名及び等しいインポート優先順位をもち, 同一の属性を含む二つの属性集合が存在する場合,その属性をも包むもっと高いインポート優先順位をもつ属性集合の定義が存在しなければ, エラーとする。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合,最も高いインポート優先順位をもつ属性を指定する定義の中から,スタイルシートにおいて最後に指定されたものを選択することによって,エラーから回復しなければならない。属性集合の属性がどこで指定されたかは,属性を属性集合に併合することだけに関係する。属性集合が使用されるとき, それに区別はない。

7.2 テキストの生成

テンプレートは, テキストノードを含むこともできる。 [3.4 空白の削除]で規定されるとおり,空白を削除した後で残るテンプレートの中の各テキストノードは,結果木に同一の文字列値をもつテキストノードを生成することになる。結果木において隣接するテキストノードは,自動的に併合される。

テキストは, 木レベルで処理されることに注意されたい。したがって,テンプレートの中の&lt;のマーク付けは,<という文字を含むテキストノードによって,スタイルシート木に表示されることになる。これは,<という文字を含む結果木のテキストノードを生成し,それが, XML文書として結果木が表現される際に,&lt;のマーク付け(又は等価な文字参照)によって表示されることになる。ただしこれは,[16.4 出力エスケープの無効化]に示されるとおり,出力エスケープが無効化されていない場合に限る。

<!-- Category: instruction -->
<xsl:text
  disable-output-escaping = "yes" | "no">
  <!-- Content: #PCDATA -->
</xsl:text>

リテラルデータ文字は,xsl:text要素の中にラップされてもよい。 このラッピングは,どの空白文字が削除されるか([3.4 空白の削除]を参照。)を変更してもよいが, XSLTプロセサによってその後文字がどのように扱われるかには影響しない。

備考 XSLTは,xml:lang属性及びxml:space属性を特別には扱わない。特に次の点に注意すること。

7.3 処理命令の生成

<!-- Category: instruction -->
<xsl:processing-instruction
  name = { ncname }>
  <!-- Content: template -->
</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>

これは, 次の処理命令を生成する。

<?xml-stylesheet href="book.css" type="text/css"?>

name属性をインスタンス化する結果生じた文字列が, NCNameでもPITargetでもない場合, エラーとなる。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合, 処理命令を結果木に追加しないことによって,エラーから回復しなければならない。

備考 これは,xsl:processing-instructionがXML宣言を出力するために使用できないことを意味する。その代わりに,xsl:output要素を使用することが望ましい([16 出力]参照)。

xsl:processing-instructionの内容をインスタンス化することが,テキストノード以外のノードを生成する場合, エラーとする。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合は,問題のあるノードをその内容とともに無視することによって,エラーから回復しなければならない。

xsl:processing-instructionの内容をインスタンス化した結果が?>という文字列を含む場合, エラーとする。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合は,後に>が付くすべての?の発生の後にスペースを1個挿入することによって, エラーから回復しなければならない。

7.4 コメントの生成

<!-- Category: instruction -->
<xsl:comment>
  <!-- Content: template -->
</xsl:comment>

xsl:comment要素はインスタンス化されて,結果木においてコメントノードを生成する。xsl:comment要素の内容は,コメントノードの文字列値に関するテンプレートとする。

次に例を示す。

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

これは, 次のコメントを生成する。

<!--This file is automatically generated. Do not edit!-->

xsl:commentの内容のインスタンス化が,テキストノード以外のノードを生成する場合は, エラーとする。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合,問題のあるノードをその内容とともに無視することによって,エラーから回復しなければならない。

xsl:commentの内容をインスタンス化した結果が,文字列--を含むか,-で終わる場合は, エラーとする。XSLTプロセサは, エラーを通知してもよい。エラーを通知しない場合,もう一つの-が後につくすべての-の後,又はコメントの末尾にあるすべての-の後にスペースを1個挿入することによって, エラーから回復しなければならない。

7.5 コピー

<!-- Category: instruction -->
<xsl:copy
  use-attribute-sets = qnames>
  <!-- Content: template -->
</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>

このとき,次を簡単に実行できる。

<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によるテキストの生成

<!-- Category: instruction -->
<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属性の値と, 現ノードの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>

もう一つの例として,次は, given-name及びfamily-nameの子供要素をもつperson要素からHTMLの段落を生成する。 段落は,後にスペースが付く現ノードの最初のgiven-name子要素の文字列値と, 現ノードの最初の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属性をもつとき,セキュリティレベルはその手続きに最も近い要素によって決定されることも仮定する。

<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名前空間勧告に適合しない。

次の例は,ソースの中のphotograph要素からimg結果要素を生成する。img要素のsrc属性の値は,image-dir変数とphotograph要素のhref子の文字列値とから計算される。img要素のwidth属性の値は, photograph要素のsize子のwidth属性の値から計算される。

<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重の波括弧に置換されることになる。右の波括弧が,二つ目の右波括弧が続くことなく,式の外側の属性値テンプレートの中に出現する場合,エラーとする。 式中のリテラル 内にある右波括弧は,式を終了するものとして認識されない。

波括弧は, 式の内部で再帰的に認識されない。次に例を示す。

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

これは, 許容されない。代わりに, 簡単に次のとおりとする。

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

7.7 番号付け

<!-- Category: instruction -->
<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 数値から文字列への変換属性]で指定される属性を用いて,文字列に変換される。この文脈では,これらの属性のそれぞれの値は,属性値テンプレートとして解釈される。変換後, 結果のストリングは, 結果木に挿入される。

次の例は,順序付きリストの項目を番号付けする。

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

次の二つの規則は,title要素を番号付けする。これは,一連の付録を後に付けた一連の章を含む文書を意図している。そこでは,章(chapter)も付録(appendix)も節(section)を含み,節は,小節(subsection)を含む。章は, 1, 2, 3と番号付けされ,付録は, A, B, Cと番号付けされる。章の中の節は, 1.1, 1.2, 1.3と番号付けされ,付録の中の節は, 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>

次の例は,章の中の備考(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分類をもつどの文字をも意味する。 英数文字のトークン(フォーマットトークン)は,リストの各数値に使用されるフォーマットを指定する。最初のトークンが非英数文字のトークンであると,構成される文字列は, そのトークンで始まる。最後のトークンが非英数文字であると,構成される文字列は, そのトークンで終わる。二つのフォーマットトークンの間に現れる非英数文字のトークンは,リストの数値を結合するために使用される分離子のトークンとする。 n番目のフォーマットトークンは,リストのn番目の数値をフォーマットするために使用される。フォーマットトークンよりも多くの数値が存在すると,最後のフォーマットトークンが残りの数値をフォーマットするために使用される。フォーマットトークンがない場合,すべての数値をフォーマットするために, 1のフォーマットトークンが使用される。フォーマットトークンは,数値1を表示するために使用される文字列を指定する。2番目以降の各数値は,その数値をフォーマットするために使用されるフォーマットトークンの前にある分離子のトークンによって,前の数値と分離される。又は,分離子のトークンがない場合,.(ピリオド文字)によって分離される。

フォーマットトークンは,HTML4.0におけるOL要素のtype属性に許容される値のスーパセットとし, 次のとおり解釈される。

アルファベットのシーケンスで番号付けするとき,lang属性が, どの言語のアルファベットを使用するかを指定する。それは, [XML]xml:langと同じ範囲の値をもつ。lang値が指定されないとき,システム環境から言語を決定するのが望ましい。実装者は,番号付けをサポートする言語を文書化することが望ましい。

備考 実装者は,特定の言語でどのように番号付けするかを仮定せず,サポートしたい言語を適切に調査することが望ましい。多くの言語の番号付け規則は,英語とは大きく異なる。

letter-value属性は,文字を使用する番号付けのシーケンス間のあいまいさをなくす。 多くの言語においては,文字を使用する番号付けのシーケンスが通常二つある。一つの番号付けのシーケンスは, アルファベット順で数値を文字に割り当て, もう一つは,その言語の伝統的な別の方法で,数値を各文字に割り当てる。英語では,これらは,フォーマットトークンa及びiによって指定される番号付けシーケンスに対応する。ある言語では, 各シーケンスの最初のメンバがと同一であるため, フォーマットトークンだけではあいまいになる。alphabeticの値は,アルファベット順を指定する。 traditionalの値は, 他のシーケンスを指定する。 letter-value属性が指定されないとき,どのようにあいまいさを解決するかは実装依存となる。

備考 二つの適合XSLTプロセサが, 一つの数値を正確に同一の文字列に変換しないことがあり得る。あるXSLTプロセサは, いくつかの言語をサポートしなくてもよい。さらに, xsl:numberの属性によって指定されないどんな特定の言語に関しても,変換を実行する方法において可能なバリエーションが存在してもよい。XSLTの将来の版は,これらのバリエーションの制御を与える追加属性を提供し得る。実装者は,これに関するxsl:numberの実装固有の名前空間属性を使用してもよい。

grouping-separator属性は,10進の番号付けシーケンスにおけるグループ化(例えば千の)分離子として用いる分離子を与え,オプションのgrouping-sizeは,グループ化のサイズ(通常は3)を指定する。例えば,grouping-separator=","及びgrouping-size="3"は, 1,000,000という形式の数値を生成する。grouping-separator属性及びgrouping-size属性の一つだけが指定されると, その指定は無視される。

変換規定の例を次に示す。

8 繰返し

<!-- Category: instruction -->
<xsl:for-each
  select = node-set-expression>
  <!-- Content: (xsl:sort*, template) -->
</xsl:for-each>

結果が既知で通常の構造をもつとき,選択したノードに関してテンプレートを直接指定できることは有効となる。xsl:for-each命令は,テンプレートを含み,それは, select属性が指定するによって選択された各ノードに関してインスタンス化される。 select属性は必須とする。 式は, ノード集合に対して評価しなければならない。 テンプレートは,現ノードとして選択されたノードを用いて, 及び現ノードリストとして選択されたすべてのノードのリストを用いて, インスタンス化される。 ソート規定が存在しない場合は,ノードは文書順に処理される([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 がある。 xsl:if命令は,単純なif-then条件を提供する。 xsl:choose命令は,幾つもの可能性ある場合に,一つの選択肢を選ぶことをサポートする。

9.1 xsl:ifによる条件付き処理

<!-- Category: instruction -->
<xsl:if
  test = boolean-expression>
  <!-- Content: template -->
</xsl:if>

xsl:if要素は, test属性をもつ。この属性は, を指定する。 内容は, テンプレートとする。式は評価され,boolean関数への呼出しを用いたように,結果オブジェクトが論理値に変換される。 結果が真である場合,内容のテンプレートはインスタンス化される。そうでない場合は,何も生成されない。 次の例では,名前のグループの中の名前が, カンマで分離されたリストとしてフォーマットされる。

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

次の例では,表の行を1行おきに黄色に着色する。

<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による条件付き処理

<!-- Category: instruction -->
<xsl:choose>
  <!-- Content: (xsl:when+, xsl:otherwise?) -->
</xsl:choose>

<xsl:when
  test = boolean-expression>
  <!-- Content: template -->
</xsl:when>

<xsl:otherwise>
  <!-- Content: template -->
</xsl:otherwise>

xsl:choose要素は,多くの可能な選択肢のから一つを選択する。 この要素は,オプションのxsl:otherwise要素が後続するxsl:when要素のシーケンスから構成される。各xsl:when要素は, 単一の属性testをもち, この属性は, を指定する。 xsl:when要素及びxsl:otherwise要素の内容は, テンプレートとする。xsl:choose要素が処理されると,各xsl:when要素は,式を評価することによって,及びboolean関数への呼出しを行ったように結果オブジェクトを論理値に変換することによって, 順にテストされる。 テスト結果が真である最初のxsl:when要素だけの内容が, インスタンス化される。xsl:whenが真でなければ,xsl:otherwise要素の内容がインスタンス化される。 xsl:when要素が真でなく,xsl:otherwise要素が存在しないときは,何も生成されない。

次の例は,順序付きリストがネストされる深さに従って,アラビア数字,アラビア文字又はローマ数字を用いる順序付きリストの項目を列挙する。

<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要素を追加することによって指定される。最初のxsl:sortの子は,1次ソートキーを指定し,2番目のxsl:sortの子は, 2次ソートキーを指定し, 以降同様とする。 xsl:apply-templates要素又はxsl:for-each要素が, 一つ以上のxsl:sortの子供をもつとき,選択されたノードを文書順に処理する代わりに,それは, 指定されたソートキーに従ってノードをソートし,ソート順にそれらを処理する。xsl:for-each要素で使用されるとき, xsl:sort要素は最初に現れなければならない。テンプレートがxsl:apply-templates及びxsl:for-eachによってインスタンス化されるとき,現ノードリストは,ソート順に処理されるノードの完全リストで構成される。

xsl:sortは,値がであるselect属性をもつ。処理対象の各ノードについては,式は,現ノードとしてのノードと, 現ノードリストとして非ソート順に処理されるノードの完全リストとを用いて, 評価される。結果オブジェクトは,string関数への呼出しを行ったように,文字列に変換される。この文字列は,そのノードのソートキーとして使用される。 select属性のデフォルト値は.であり,このため,現ノードの文字列値が, ソートキーとして使用されることになる。

この文字列は, そのノードに関するソートキーとして動作する。 xsl:sortに関する次に示すオプションの属性は,ソートキーのリストをどのようにソートするかを制御する。これらの属性のすべての値は, 属性値テンプレートとして解釈される。

備考1 二つの適合するXSLTプロセサが,厳密に同一の結果をソートしないこともあり得る。あるXSLTプロセサは, 幾つかの言語をサポートしなくてもよい。 さらに,xsl:sortの属性が指定しない特定の言語のソートにおいて,バリエーションがあり得る。例えば,日本語において,ひらがな又はカタカナのどちらを先にソートするかというバリエーションがある。XSLTの将来の版は,これらのバリエーションの制御を与えるために,追加属性を提供してもよい。実装者は,これに関するxsl:sortの実装固有の名前空間属性を使用してもよい。
備考2 実装者が,国際化されたソートの情報に関する[UNICODE TR10]を調査することを推奨する。

ソートは安定していなければならない。ノードのソート済みリストにおいて,すべて等しいとするソートキーをもつどの部分リストも文書順になければならない。

例えば, 従業員データベースが次の形式をもつとしよう。

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

名前によってソートされる従業員のリストは, 次を用いて生成される。

<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 変数及びパラメタ

<!-- Category: top-level-element -->
<!-- Category: instruction -->
<xsl:variable
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:variable>

<!-- Category: top-level-element -->
<xsl:param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:param>

変数とは,ある値に束縛されてもよい名前とする。変数が束縛される値,すなわち,変数のは,式が返すことのできる型のいずれのオブジェクトでも可能とする。変数を束縛するために使用できる要素が二つ存在する。それらは,xsl:variable及びxsl:paramとする。xsl:param変数に指定される値は,束縛のデフォルト値だけとする点を,両者の相違点とする。xsl:param要素が出現するテンプレート又はスタイルシートが呼び出される場合,デフォルト値の代わりに,使用するパラメタを渡してもよい。

xsl:variable及びxsl:paramの両方とも,必須のname属性をもつ。この属性は,変数の名前を指定する。name属性の値は,QNameであって,これは,[2.4 修飾された名前]で示されるとおりに拡張される。

これら変数束縛要素をどのように使用しても,束縛が見えているスタイルシート木の範囲が存在する。この範囲内では,変数束縛要素それ自体においては見えていた変数の束縛が隠蔽される。したがって,最も内側にある変数の束縛だけが見えることになる。式の有効範囲内にある変数の束縛の集合は,式がスタイルシートに出現する時点で見えている束縛から構成される。

11.1 結果木素片

変数は,付加的なデータ型を式言語に導入する。この付加的なデータ型を結果木素片と呼ぶ。四つの基本Xpathデータ型であるstring,number,boolean又はnode-setの一つの代わりに結果木素片に変数を束縛してもよい。結果木素片は,結果木の素片を表現する。結果木素片は,単一の根ノードだけを含むノード集合と等価に扱われる。しかし,結果木素片に関して許可される演算は,ノード集合に関して許可される演算の部分集合とする。演算が文字列に関して許可される場合に限り,結果木素片でその演算が許可される。ただし,文字列に関する演算は,最初に文字列から数値又は論理値への変換処理を含んでもよい。特に,結果木素片では,演算子///及び[]の使用は許可されない。許可された演算が結果木素片に関して実行されると,等価なノード集合に関して演算が実行されたのと全く同じに実行される。

結果木素片が結果木にコピーされる場合([11.3 xsl:copy-ofによる変数値及びパラメタ値の使用]を参照),等価なノード集合における根ノードの子供であるすべてノードが,順番どおりに結果木に追加される。

式は,結果木素片の変数を参照する,結果木素片を返す拡張関数を呼び出す,又は値が結果木素片であるシステム特性を獲得することによってだけ,結果木素片の型の値を返すことができる。

11.2 変数値及びパラメタ値

変数束縛要素は,次の三つのいずれかの方法で,変数の値を指定できる。

備考 位置によってノードを選択するために変数を使用する場合は,次をしないように注意すること。
<xsl:variable name="n">2</xsl:variable>
...
<xsl:value-of select="item[$n]"/>
変数nは数値ではなく結果木素片に束縛されるので,この記述では,最初のitem要素の値を出力することになる。この代わりに,次のとおりにするのがよい。
<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による変数値及びパラメタ値の使用

<!-- Category: instruction -->
<xsl:copy-of
  select = expression />

xsl:copy-of要素を使用して,結果木に結果木素片を挿入することができる。この場合,xsl:value-ofのように,最初に文字列に変換する必要はない([7.6.1xsl:value-ofによるテキストの生成]を参照)。必須のselect属性は,を含む。式を評価した結果が結果木素片である場合は,完全な素片が,結果木にコピーされる。結果がノード集合である場合は,その集合におけるすべてのノードが,文書の順に結果木にコピーされる。要素ノードをコピーすると,要素ノードそれ自体だけでなく,その要素ノードの属性ノード,名前空間ノード及び子供もコピーされる。根ノードは,その子供をコピーすることによって,コピーされる。結果がノード集合でも結果木素片でもない場合は,xsl:value-ofを使用する場合と同様に,その結果は文字列に変換され,それから,結果木に挿入される。

11.4 最上位の変数及びパラメタ

xsl:variable及びxsl:paramの両方が,最上位要素として許される。最上位の変数結合要素は,どこからでも見える大域変数を宣言する。最上位のxsl:param要素は,スタイルシートへのパラメタを宣言する。ただし,XSLTは,パラメタをスタイルシートに渡す機構を定義しない。一つのスタイルシートに同じ名前及び同じインポート優先順位をもつ最上位の変数の束縛が二つ以上含まれる場合は,エラーとする。最上位では,変数の値を指定する式又はテンプレートは,ソース文書の根ノードの処理に使用される文脈と同じ文脈で評価される。現ノードはソース文書の根ノードとし,現ノードリストはソース文書の根ノードだけを含むリストとする。大域変数 x の値を指定するテンプレート又は式が大域変数 y を参照する場合は,y に対する値が x の値の前に計算されなければならない。大域変数のすべての定義に対し