XSLT2.0で便利になった機能(2) as属性による型付け

XSLT 2.0で最も1.0と異なる点は、as属性による「型付け」ができるようになったことではないでしょうか?as属性は、<xsl:variable>, <xsl:param>,<xsl:with-parm>だけでなく、<xsl:template>や<xsl:function>にも戻り値としてにも記述できます.XSLT 1.0と<xsl:variable>を例に比べてみましょう.XSLT 1.0では、
 
<xsl:variable name="lang">
    <xsl:choose>
        <xsl:when test="@xml:lang">
            <xsl:value-of select="@xml:lang"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="'en'"/>
        </xsl:othewise>
    </xsl:choose>
</xsl:variable>
 
と書くと、$langは言語コードをテキストとしてもつ変数となります.XSLT 2.0でas属性をつけて書くと次のようになるでしょうか.
 
<xsl:variable name="lang" as="xs:string">
    <xsl:choose>
        <xsl:when test="@xml:lang">
            <xsl:sequence select="@xml:lang"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:sequence select="'en'"/>
        </xsl:othewise>
    </xsl:choose>
</xsl:variable>
 
XPath 2.0のif~then~elseを使うと一行で済みます.便利ですね.使い出すと病み付きになります.
 
<xsl:variable name="lang" as="xs:string" select="if (@xml:lang) then string(@xml:lang) else 'en'"/>
 
as属性に書く値はsequence type descriptorと呼ばれ、item()を頂点とする型の階層から記述することができます.例えばnode(), element(), attribute()、またXML Schemaで定義されている、xs:integer, xs:string, xs:booleanなどが使えます.後者を使用するときは、
 
 
のネームスペース宣言が必要になります.またOccurence Indicatorと呼ばれる、*, +, ?をこれらの後に書くことができます.
さて、asを使って一番スリリングなのは、xsl:paramに使った場合ではないでしょうか?私はXSLT 1.0で書いたxsl:templateのxsl:paramをas属性を追加して書き直しましたが、案の定エラーが出ました.element()であるべきところに、2つのelement()のシーケンスが渡ってしまったのです.こんなXPath式だったと思います.同じキーに該当する要素が二つ存在してしまったためです.
<xsl:variable name="topicRef" select="key('bookmapByHref',$href)"/>
テンプレートに渡す変数を$topicref[1]としてすぐ動くようになりましたが、XSLT 1.0では何故動いていたのか疑問になりました.(もうXSLT1.0に戻ることはないので深追いしませんでしたが...)