異なるノードを取得する際の問題は、2 つのノードが異なることをどのように判断するかということです。これは、XML の複雑なトピックです。複製ノードが同じノード ID を持つ場合 (つまり、同じノードを参照する場合)、functx:distinct-nodes() のような関数を使用できます。それ以外の場合は、ノードが等しいと見なされるのに「十分に等しい」かどうかを判断するために、何らかのタイプのハッシュが必要です。
<author>
姓と名が同じで2 つの s が等しい場合concat(last,first)
、ハッシュのような単純なものを使用して、xpath を使用して個別の値を取得できます。
$xml/author[index-of($xml/author/concat(last,first), concat(last,first))[1]]
すべてのステップでハッシュを計算しているため、これはまだ理想的ではありません。そのため、大規模なデータセットでは速度が低下します。パフォーマンスを向上させるためにできることの 1 つは、データのハッシュを事前に計算することです。
<author hash="ShakespearWilliam">
<last>Shakespear</last>
<first>William</first>
</author>
と:
$xml/author[index-of($xml/author/@hash, @hash)[1]]
ハッシュによって順序付けられたノードを効率的に取得できる場合 (理想的には順序付けられたデータベース インデックスを使用)、重複を削除するより効率的な方法があります。
declare function local:nodupes($first, $rest)
{
if (empty($rest)) then $first
else if ($first/@hash eq $rest[1]/@hash)
then local:nodupes($rest[1], subsequence($rest,2))
else ($first, local:nodupes($rest[1], subsequence($rest,2)))
};
次に、順序付きセットでそれを呼び出します。
let $ordered :=
for $a in $xml/author
order by $a/@hash
return $a
return
local:nodupes((),$ordered)