何もしないXSLT part.3

何も変更しないXSLTの書き方のXSLT 3.0版をメモしておく。


要点は追加された「on-no-match」という指定。「テンプレートが見つからなかった時」という指定だ。
テンプレートが見つからなかった時はデフォルトのテンプレートが適用されることになっていたのだが、デフォルトのテンプレートの設定を切り替えることができるようになった。
2.0以前はこれが「text-only-copy」という値で固定されていたと考えるといいらしい。今もデフォルトはこれだ。テキストオンリーなので、基本は中身の文字が残る。


下の例にあるように、この値をshallow-copyにするとほとんど何も書かなくてもよくなる。
shallow-copyのshallowは「次の一段階はコピーを適用するが、そこに要素とかがあったらテンプレートを適用せよ」という意味で「浅い」ということらしい。
deepだと「中身の解釈は無視する」。deep-copyはxsl:copyと同じらしい。


設定値は

  • text-only-copy
  • shallow-copy
  • deep-copy
  • shallow-skip
  • deep-skip
  • fail

skipは「中身を捨てる」処理で、shallowなら「中にある要素とかはもう一度テンプレートにかける」がdeepなら「全部捨てる」になる。
failはエラーをはいて変換を止めるための記述。


on-no-matchは本来はモード*1に関する設定なのでモードの名称を指定して属性をセットするものである。
下の記述がよくわからない宣言になっているのは「デフォルト名無しのモード」に対しての宣言だから名前の記述がないせいである。*2
動作モードという全体設定値を変更しているのではない(笑)


3.0はXSLTスタイルシートのパッケージ化とかなかなか豪快な追加仕様があるのだが、あまり使ったことがない。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">
    
    <xsl:mode on-no-match="shallow-copy"/>
    
    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>
    
</xsl:stylesheet>

*1:XSLTテンプレートのグループ分けをするためのシステム。私は同じ形の名前データでも日本人とアメリカ人で「姓名」「名姓」の順に出力を切り替えたいという時とかによく使う。そういえば、その部分ではモードが違うから注意が必要なのか。

*2:デフォルトじゃなくunnamedだった。そういえばデフォルトのモードのモード名を宣言する方法があったな。まぁデフォルトのデフォルトのモードはunnamedだけど。 https://www.saxonica.com/html/documentation12/xsl-elements/mode.html