XSLT2.0で便利になった機能(53) use-when属性

今まで10年以上XSLT1.0で動かしてきたシステムが、Word2003のサポート終了でWord2013へ移行することになりました.Word2003の出力するWordMLを使用してきたのですが、同じWordMLでもWord2013の吐き出すWordMLは相当毛色が違います.

実際にWord2013の出したWordMLで動かしてみると案の定まともに動いてくれません.なんとか直さなければならないのですが、一晩考えて、XSLT1.0で書いたスタイルシートではもう限界と悟り、XSLT2.0に移行することにしました.XSLTプロセッサを呼び出すのはSwingで作ったJavaGUIなのですが、JAXPを使用しています.

JAXP(Java API for XML Processing)

このため、修正することは変換に使用するXSLTプロセッサのクラス名をcom.icl.saxon.TransformerFactoryImpl(Saxon 6.5)から、net.sf.saxon.TransformerFactoryImpl(Saxon 9.x)に変えてビルドすれば出来ちゃいます.ここがJAXPのいいところです.たった1行の修正でした.

さてスタイルシートをXSLT2.0にデバッグを進めるうちに、ちょっとスタイルシートの動作を一時的に変えて結果を比較しなければならなくなりました.

通常だったらxsl:paramを使用してパラメータを渡して動作を変えます.でも呼び出し側がJavaアプリケーションなので、またそのためコーディングを入れて、.jarをビルドしなかればなりません.急いでいるときに考えただけでもイヤになります.こういう時に使えるのがXSLT2.0のuse-when属性です.例えば、出力動作を変更するxs:boolaen値を格納する変数を以下のようにスタイルシートで定義します.

<xsl:variable name="skipIncludeTextResult" as="xs:boolean" select="false()" use-when="system-property('skip.includetext.result') eq 'false'"/>
<xsl:variable name="skipIncludeTextResult" as="xs:boolean" select="true()" use-when="not(system-property('skip.includetext.result') eq 'false')"/>

こうしておいてGUIを起動するJavaコマンドラインで、-Dskip.includetext.result="false" としてやれば、前者の$skipIncludeTextResultが採用され値はfalse()になります.コマンドラインにこのパラメータを指定しなければ後者の$skipIncludeTextResultが採用され値はtrue()になります.

あとは$skipIncludeTextResultを参照して動作を変えるコードを入れるだけです.

@use-whenは結構便利に使えます.以前はxsl:include(xsl:import)を制御するのに使っていましたが、ちょっとしたテストのためにスタイルシートの動作を変更したいときにもいいかもです.