XSLT2.0で便利になった機能(7) castable asを使ってみる

XSLT2.0ではご存知のようにXPath2.0が使えます.XPath2.0は1.0に比べて格段に変わっています.ここでは、そのなかの一つcastableオペレータを使って、データチェックができることを紹介します.
 
XSLTで実際データチェックなんてやるのか?という方もいらっしゃると思いますが、私の携わったシステムではやっています.まだDTDを使っているので年月日のデータが妥当であるかはパーサーではチェックできないからです.
 
例えばDocBookを例にとって、年のチェックを行って見ましょう.まず   
 
 
とネームスペースを宣言するものとします.そして以下のように年を変数に格納します.
 
<xsl:variable name="copyrYear" as="xs:string">
    <xsl:variable name="tempCopyrYear" as="text()*">
        <xsl:apply-templates select="/db:book/db:info/db:copyright/db:year[1]" mode="TEXT_ONLY"/>
    </xsl:variable>
    <xsl:sequence select="string-join($tempCopyrYear,'')"/>
</xsl:variable>
 
<xsl:template match="*" mode="TEXT_ONLY">
    <xsl:apply-templates mode="TEXT_ONLY"/>
</xsl:template>
 
ここで、$copyrYearが数値であるかチェックするのですが、XSLT1.0では
 
<xsl:if test="string(number($copyrYear))='NaN' or
                 translate($copyrYear,'0123456789','')!=''">
    <xsl:message terminate="yes">Copyright year is invalid. value='<xsl:value-of select="$copyrYear"/>'</xsl:message>
</xsl:if>
 
とやるのがせいいっぱいです.XSLT2.0ではcastable asオペレータを使えばもっと簡単にできます.
 
<xsl:if test="not($copyrYear castable as xs:integer)">
    <xsl:message terminate="yes">Copyright year is invalid. value='<xsl:value-of select="$copyrYear"/>'</xsl:message>
</xsl:if>
 
$copyrYear castable as xs:integerは、$copyrYearが整数にキャスト可能であれば真を返してくれます.ちなみに、2010.1 castable as xs:integerは偽を返します.問題ありません.
 
いったん整数値であることが確認できれば次のように記述することもできます.
 
<xsl:variable name="intCopyrYear" as="xs:integer" select="xs:integer($copyrYear)"/>
<xsl:if test="$intCopyrYear lt 2000 or $intCopyrYear ge 2011">
    <xsl:message terminate="yes">Year is invalid. value='<xsl:value-of select="$copyrYear"/>'</xsl:message>
</xsl:if>
 
xs:integer($copyrYear)は、xs:integerのconstructor functionと呼ばれ引数をxs:integerに変換してくれます.またcast as を使って、
 
<xsl:variable name="intCopyrYear" as="xs:integer" select="cast $copyrYear as xs:integer"/>
とも書けます.