ちょっと前に戻って、ちょっとだけ便利になった話をしたいと思います.テーマは is オペレータです.
新しく導入されたis オペレータは前後にノードのオペランドをもち、そのノードが同一か判定し結果をxs:booleanで返します.ここで「ノードが同一」というのは、入力ドキュメント中でたまたま要素名やテキスト、アトリビュート名/値が同じノードだということではなくて、「まったく同じ位置のノード」であるということです.つまり $a is $b は$aと$bが同じノードをポイントしていることを示します.
では何故このようなものが必要なのでしょうか?例えばこんな例があります.以前DITAの索引をやっていました.DITAの中間ファイルは、DITA Open Toolkitで作成され、簡単にいうと、topicrefからなるmapの部分と、一連のtopicのからなるtopic部分があります.topicはmapのtopicrefから@hrefで参照されています.
DITAの索引の仕様はいやらしくて、mapのtopicref/topicmetaに書かれた<indexterm start="intro">Introduction</indexterm>のような、@endをもたない範囲を示すindextermは「最終のtopicref」の処理時に自動的に<indexterm end="intro"/>を自動生成してやらねばなりません.
indextermの仕様は以下のURLに書かれています.
ではどうやってやるかといいますとこんな具合です.
<xsl:variable name="root" select="/*[1]" as="element()"/>
<xsl:variable name="map" select="$root/*[contains(@class,' map/map ')][1]" as="element()"/>
<xsl:variable name="lastTopicref" select="$map/descendant::*[contains(@class,' map/topicref ')][@href][not(ancestor::*(contains(@class, ' map/reltable ')))][position()=last()]" as="element()"/>
<xsl:variable name="map" select="$root/*[contains(@class,' map/map ')][1]" as="element()"/>
<xsl:variable name="lastTopicref" select="$map/descendant::*[contains(@class,' map/topicref ')][@href][not(ancestor::*(contains(@class, ' map/reltable ')))][position()=last()]" as="element()"/>
<xsl:template match="*[contains(@class, ' map/topicref ')]">
<!-- 本来のtopicrefの処理
(対応するtopicの中身を処理する)-->
<!-- 本来のtopicrefの処理
(対応するtopicの中身を処理する)-->
<xsl:if test=". is $lastTopicref">
<!-- indexterm/@startで対となるindexterm/@endがない場合、
indexterm/@endに対応するオブジェクトの生成 -->
</xsl:if>
</xsl:template>
<!-- indexterm/@startで対となるindexterm/@endがない場合、
indexterm/@endに対応するオブジェクトの生成 -->
</xsl:if>
</xsl:template>
XSLT1.0の場合はどうだったでしょうか?たぶん
<xsl:if test="generate-id()=generate-id($lastTopicref)">
とやったでしょう.ほとんど変わりがない?はい、ですからちょっとだけ便利になった話です.