閑話休題: 比較演算子(2)

前回比較演算子のことについて書きましたが、まだ例はAtomic valueとシーケンスの比較でした.シーケンス同士の比較になると、知っておいた方が良いことがあります.(実際のスタイルシートで問題になるということはほとんどないと思いますが...)
 
■ "="も"!="も真(true)になる.
 
<xsl:variable name="s" select="'Apple','Orange','Melon','Pear','Cherry'" as="xs:string*"/>
 
とします.ここで、$s='Orange'と$s!='Orange'はどうなるでしょうか?
 
<xsl:message select="'$s=''Orange'':',if ($s='Orange') then 'true' else 'false'"/>
<xsl:message select="'$s!=''Orange'':',if ($s!='Orange') then 'true' else 'false'"/>
 
結果は
 
$s='Orange': true
$s!='Orange': true
 
です.$sには'Orange'のメンバーもあるし、'Orange'でないメンバーも存在するからです.そうすると自身との比較も同じことになります.
 
<xsl:message select="'$s=$s:',if ($s=$s) then 'true' else 'false'"/>
<xsl:message select="'$s!=$s:',if ($s!=$s) then 'true' else 'false'"/>
 
$s=$s: true
$s!=$s: true
 
■ 自身との"="も"!="も偽(false)になる.
一般的にはないのですが、次のような場合にそうなります.
 
<xsl:variable name="e" select="()" as="xs:string*"/>
 
の場合、
 
<xsl:message select="'$e=$e:',if ($e=$e) then 'true' else 'false'"/>
<xsl:message select="'$e!=$e:',if ($e!=$e) then 'true' else 'false'"/>
 
は、
 
$e=$e: false
$e!=$e: false
 
となります.empty($e) eq true() なので、一致するメンバーも、一致しないメンバーもないからです.
当然ヌルシーケンスとそうでないものの比較も同じ結果になります.
 
<xsl:message select="'$e=$s:',if ($e=$s) then 'true' else 'false'"/>
<xsl:message select="'$e!=$s:',if ($e!=$s) then 'true' else 'false'"/>
 
$e=$s: false
$e!=$s: false
 
■ $s=$s2、$s=s3 でも $s2=$s3とは限らない.
ここまでくればもはや自明ですが、一応見てみましょう.
 
<xsl:variable name="s" select="'Apple','Orange','Melon','Pear','Cherry'" as="xs:string*"/>
<xsl:variable name="s2" select="'Apple','Orange'" as="xs:string*"/>
<xsl:variable name="s3" select="'Pear','Cherry'" as="xs:string*"/>
 
の場合、
 
<xsl:message select="'$s2=$s:',if ($s2=$s) then 'true' else 'false'"/>
<xsl:message select="'$s3=$s:',if ($s3=$s) then 'true' else 'false'"/>
<xsl:message select="'$s2=$s3:',if ($s2=$s3) then 'true' else 'false'"/>
 
$s2=$s: true
$s3=$s: true
$s2=$s3: false
 
となります.$s2と$s3のシーケンスには共通するメンバーは存在しないからです.
 
考えてみれば、シーケンス$xがm個、シーケンス$yがn個のメンバーをもっていれば、$x=$yの比較は最大でm×nの比較を伴います.XSLTプロセッサは最適化するでしょうが、一般比較演算子はやはりコストのかかるものと考えた方が良いですね.