XSLT3.0への道(35) 変わるDITAのテンプレート

XSLT 3.0を使用するようになると、DITAのテンプレートも変わります.DITA-OT( DITA Open Toolkit)は3.xになってからついてくるSaxon HEのバージョンを9.8に変えました.なのでXSLT 3.0で自由にプラグインスタイルシートがかけるようになります.

と言っても、DITA-OT本体のコードはまだXSLT 2.0のままですが...

今回HTMLのプラグインを新規作成する機会があったので、これぞとばかりにすべてXSLTスタイルシートのバージョンを3.0に上げてみました.

例えば、今まででしたらDITAの要素にマッチングさせるテンプレートは次のように書いていたはずです.

<xsl:template match="*[contains(@class, ' topic/title ')]">

でも考えてもわかるんですが、containsというのは文字列をなめて一致を判定しなければならないのでトータルで見ると遅いですよね.DITAのコミュニティからの要望をうけてXSLT 3.0のエディタのMichael Kay博士はcontains-tokenという関数を追加してくれました.

5.3.9 fn:contains-token

https://www.w3.org/TR/xpath-functions-31/#func-contains-token

 これを使用すると、次のようにテンプレートの書き方が変わります.

<xsl:template match="*[contains-token(@class, 'topic/title')]">

 ご覧いただくとわかりますが、' topic/title 'の指定は、'topic/title'に代わります.これは、@classを文字列に置き換えて、ホワイトスペースを区切り文字としてトークンを切り出すためです.

たかだかこれだけとバカにすべきではありません.膨大なDITAの文書を処理する時、逐次文字検索のcontainsと、トークンに切り出して判定するcontains-tokenとでは、スピードに差が出ること必至です.

このコーディングでもいいのですが、私はもうちょっとカッコをつけて次のコーディングスタイルにしています.

<xsl:template match="*[@class => contains-token('topic/title')]">

これだと「@class属性に」「'topic/title'がトークンとして含まれているか?」という日本語の順序にあった書き方になるからです.

ここで使われている"=>"は以前紹介した演算子で、左辺を右辺の関数の第1引数として渡してくれるものです.

Arrow operator

https://www.w3.org/TR/xpath-31/#id-arrow-operator

あとよくあるパターンとして、@class属性がAかBに一致というマッチングパターンが良く出てきます.これもXSLT 3.0で書くとずっと簡単になります.次回に紹介させてもらいます.