閑話休題:Saxonでのデバッグ

XSLT2.0で便利になった機能(1)でtunnelパラメータについて書きましたが、現在DITA→XSL-FOのスタイルシートでパラメータのtunnel化を進めています.
 
やり方はパラメータ値が確定したところで、
 
<xsl:with-param name="pamLang" tunnel="yes" select="..."/>
 
とtunnelの「入口」を作ります.最後の$prmLangを必要とするテンプレートで
 
<xsl:param name="pamLang" tunnel="yes" required="yes"/>
 
でtunnelの「出口」を作ります.
 
あとはひたすら中間のテンプレートから、$prmLangを<xsl:param>と<xsl:with-param>を削除するだけ.と思っていたのですが、いざ動かしてみるとあにはからんや、下記のエラーが出てしまいました.
 
XTDE0700: No value supplied for required parameter
 
これは大変!何故って、最後の$prmLangを必要とするテンプレートは約200箇所(!)から呼ばれているのです.どこから呼ばれているのかなんてデバッガを使わないと分かりません.
 
ところが実はXSLTのデバッガを持っていないのです.日常はほとんど<xsl:message>によるコンソールデバッグだけです.
このようなときSaxonは心強いオプションを持っています.それは"-t"パラメータ.これがあると、ログに次のようにこけたときのトレースを出してくれます.
 
[java] Saxon 9.1.0.5J from Saxonica
[java] Java version 1.6.0_20
[java] Stylesheet compilation time: 2203 milliseconds
[java] Processing file:/D:/DITA-OT1.5-FB/out/XXX_user_guide_bookmap_CONVERTED.xml
[java] Building tree for file:/D:/DITA-OT1.5-FB/out/XXX_user_guide_bookmap_CONVERTED.xml using class net.sf.saxon.tinytree.TinyBuilder
[java] Tree built in 62 milliseconds
[java] Tree size: 9858 nodes, 75166 characters, 13000 attributes
[java] Loading net.sf.saxon.event.MessageEmitter
[java] Building tree for file:/D:/DITA-OT1.5-FB/demo/xx_pdf/config/xx_style.xml using class net.sf.saxon.tinytree.TinyBuilder
[java] Tree built in 16 milliseconds
[java] Tree size: 5635 nodes, 6945 characters, 2081 attributes
[java] Building tree for file:/D:/DITA-OT1.5-FB/demo/xx_pdf/config/xx_variables.xml using class net.sf.saxon.tinytree.TinyBuilder
[java] Tree built in 16 milliseconds
[java] Tree size: 747 nodes, 1252 characters, 332 attributes
[java] Error at xsl:param on line 124 of xx_dita2fo_xslt2util.xsl:
[java]   XTDE0700: No value supplied for required parameter
[java]   at xsl:call-template name="getAttributeSet" (file:/D:/DITA-OT1.5-FB/demo/xx_pdf/xsl/xx_dita2fo_backmatter.xsl#45)
[java]   at xsl:apply-templates (file:/D:/DITA-OT1.5-FB/demo/xx_pdf/xsl/xx_dita2fo_backmatter.xsl#39)
[java]      processing /dita-merge/bookmap[1]/backmatter[1]
[java]   at xsl:call-template name="genBackMatter" (file:/D:/DITA-OT1.5-FB/demo/xx_pdf/xsl/xx_dita2fo_main.xsl#123)
[java]   at xsl:apply-templates (file:/D:/DITA-OT1.5-FB/demo/xx_pdf/xsl/xx_dita2fo_main.xsl#61)
[java]      processing /dita-merge/bookmap[1]
[java] Transformation failed: Run-time errors were reported
 
これで原因は一発でわかりました.上位の一箇所でtunnel="yes"を<xsl:with-param>に入れ忘れていたのです.
 
DITA Open Toolkitを使っていて、Saxonはantからxsltタスクで呼んでいるのですが、このときだけはjavaタスクに切り替えて"-t"が指定できるようにしています.この手のエラーが出たときは是非"-t"をお試しください.