XSLT 2.0で便利になった機能(32) xsl:message

スタイルシートデバッグするときはどのような方法を使っておられるでしょうか?この前Visual Studio 2010の試用版をインストールしたら、.xslのファイルをクリックするとVisual StudioIDEが開くようになってしまいました.Visual Studio 2010では、XslCompiledTransformクラスを使ったプログラムならデバッグできるようになっているみたいですね.でも、.netのXSLT1.0のXSLTプロセッサではXSLT2.0スタイルシートとは無縁です.

日本にはないですが、JavaベースのXSLTプロセッサには、結構デバッグツールが出回っています.私もかつて会社で社長から「これで倍に生産性が上がるなら買ってもいい」といわれて、まだ安いoXygen(http://www.oxygenxml.com/xml_editor.html)を買ってもらったのですが、悲しいかな当時のメインマシン(Pentium 1.7GHz 256MB)のスペックでは重くて重くてついに使いこなせず、結局xsl:messageのデバッグになってしまいました.まあC/C++ではprintf/MesssageBoxによる情けないデバッグ手法です.でもxsl:message terminate="no"ができないタコのMSXMLを使うよりは良いかも...
ところで、xsl:messageはどのように書いているでしょう?XSLT 1.0までの書き方をするならこんな感じです.

<xsl:if test="not(string(@month) castable as xs:integer)">
  <xsl:message terminate="yes">The month attribute is not numeric. Month="<xsl:value-of select="@month"/>"</xsl:message>
</xsl:if>

これは例えば次のように出力されます.

The month attribute is not numeric. Month=ABC
Processing terminated by xsl:message at line 11 in test.xsl

実は私はこの</xsl:message>で要素を閉じなければならないのがいやでたまりませんでした.デバッグの時はそうでなくとも時間がなくてイライラしているのに、普通のエディタを使っているので、ついつい"/"を忘れてパーサーにタグが閉じていないと怒られるからです.

XSLT2.0は、select属性が使えるようになりました.だから<xsl:message>~</xsl:message>と書かなくとも次のようにできてしまいます.

<xsl:message terminate="yes" select="'The month attribute is not numeric. Month=',string(@month)"/>

The month attribute is not numeric. Month= ABC
Processing terminated by xsl:message at line 12 in test.xsl

Saxonはシーケンスの間に空白を入れてくれるので、ちょっと表示の仕方が変わります.まあこれがイヤだったら

<xsl:message terminate="yes" select="concat('The month attribute is not numeric. Month=',string(@month))"/>

ともすれば良いでしょう.
また通常のXSLT要素はselect属性とsequence constructorが排他的ですが、xsl:messageはそうではありません.ですから例えば

<xsl:message terminate="yes" select="'The month attribute is not numeric. Month='">
    <xsl:value-of select="string(@month)"/>
</xsl:message>

ともかけるところが違います.私は</xsl:message>を書かなければならないので、使いませんが...
なお、IDEを使わないデバッグでは、xsl:commentを使うことも結構多く使われているようです.XSLT2.0では、こちらにもselect属性が使えるようになりました.

<xsl:comment select="concat('Month=',string(@month))"/>

と書けば、例えば

<!--Month=ABC-->

と出力してくれます.