😎

[XSLT 3.0]xsl:context-itemで名前付きテンプレートのコンテキストアイテム要不要を明示する

に公開

https://adventar.org/calendars/11635

XSLT 3.0デバッグまわり Advent Calendar 2025の8日目。

コンテキストアイテム

「コンテキストアイテム」の概念はXSLT 2.0からあります。 文脈(Context)の示す通り、現在の処理対象を示す「.」で表されるものです。 この時点では1.0のではnode()型に限ったコンテキストノードからitem()型全般へと拡張された、という話でした。 細かいところでは、text()node()に含まれますが、XPath式中に登場するxs:stringtext()ではないため、 match="text()"では処理対象でなかったりします。
xsl:value-ofは新規text()を生成したりするのでまたややこしいですが。

<xsl:template match="child::p">
<!-- 何かしらの子であるようなpがコンテキストアイテム -->
  <xsl:copy-of select="./child::*"/><!--child::pのchildをコピー -->
</xsl:template>

名前付きテンプレートと関数の違い

名前付きテンプレート(xsl:template[@name])はコンテキストアイテムを持てる(使える)。関数(xsl:function)は持てない。とはいえ、関数にも引数として渡してやればそれを処理することはできるので、強固に「使えない」と主張するようなものではありません。

で、名前付きテンプレートですが。
xsl:paramは明示的に持てる一方で、その名前付きテンプレートがコンテキストアイテムを必要とするのかどうかはXSLT 3.0までは形式的な把握が難しかったんですね。実は。

3.0で導入されたxsl:context-itemは名前付きテンプレートのdeclaration部で、そのテンプレートでのコンテキストアイテムについての情報を記述します。

  • そのテンプレートにコンテキストアイテムは必要なのか、どちらでもいいのか、いらないのか(@use= 'required' | 'optional' | 'absent'|)
  • そのコンテキストアイテムの型は何か(@as

「絶対にtext()がコンテキストアイテムのところで呼んでほしい」というときは次のようになります。

<xsl:template name="textAbs">
  <xsl:context-item use="required" as="text()"/> <!--コンテキストがtext()で必要 -->
  <xsl:sequence select=".  => ..."/><!-- context-item . をテンプレート内で使うよ -->
</xsl:template>

実際のところ、明示的にある型が必要な場合はxsl:paramで要求することが多いでしょう。そしてその場合はxsl:functionでもいい。
xsl:context-item@use="required"とする場合はあっても、必要とするのはnode()のケースが多くなるので、その場合は@asは書かなくてもあんまり変わらないんですよね。

ちなみに@use="absent"のときは@asは記述できません。コンテキストアイテム無しっていってるでしょ。

xsl:context-itemの使い所

これは「この名前付きテンプレートはこういうコンテキストアイテムが必要である」というインタフェースの話であるので、自分でテンプレートの内容を書くときには冗長さが勝つでしょう。自分で@select="."とか書くわけで。
つまり、自分で内容を書かないときに便利。そんなことがあるのが、@visibility="abstract"で実装を他のスタイルシートに投げたテンプレートを作るときです。

<xsl:template name="procAnotherSheet" visibility="abstract">
  <xsl:context-item use="required" />
</xsl:template>

<xsl:template match="p">
  <fo:block><!--このスタイルシートではabstractなので、別のスタイルシートで中身を書いてそれを呼び出す -->
    <xsl:call-template name="procAnotherSheet"/>
  </fo:block>
</xsl:template>

参考資料

https://www.w3.org/TR/xslt-30/#element-context-item

組版・ドキュメンテーション勉強会

Discussion