3

個別の値に似ているがノードを返すXqueryの関数があるかどうか知りたいのですが。

もっと明確にしましょう。たとえば、私は参考文献を持っており、その中の各著者について、彼が書いたすべての本をリストしたいと思います。私の特定の場合の作成者要素は次のようになります。

<author>
  <last> Shakespear </last>
  <first> William </first>
</author>

著者にdistinct-valuesを使用すると、私が見る限り、ShakespearWilliamが返されます。重複を考慮せずに要素作成者の構造を保持する関数が欲しいのですが。

クエリの別の方法を見つけたら、私に知らせてください。誰かが何か考えを持っていますか?

4

2 に答える 2

4

異なるノードを取得する際の問題は、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)
于 2012-10-02T16:27:41.260 に答える
2

XQuery 3.0 には「group by」構造があり、これにより、たとえば、著者を (名、姓) の値でグループ化できます。ノードをグループ化すると、本質的に答えが得られます。ノードは、異なるグループに属している場合にのみ区別されます。

XQuery 3.0 ドラフトのこの部分を実装する製品はかなりの数あります。Saxon 9.4 もその 1 つです。

于 2012-10-02T16:54:31.283 に答える