2012-10-02 172 views
3

我想知道是否有任何類似於distinct值但是返回節點的Xquery函數。xquery:如何獲得不同值的節點

讓我更加清楚:例如,我有一本參考書目,每位作者都想列出他寫的所有書籍。在我的具體情況筆者元素是這樣的:

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

在筆者使用不同的值,從而儘可能返回ShakespearWilliam我可以看到它並不能幫助。我想要一個保留元素作者結構而不考慮重複的函數。

如果您發現查詢的另一種方式,然後讓我知道。有人有什麼主意嗎?

回答

2

XQuery 3.0有一個「group by」構造,這允許您通過(名,姓)的值對作者進行分組。當你對節點進行分組時,你基本上有了答案:當且僅當它們在不同的組中時,節點纔是獨特的。

圍繞XQuery 3.0草稿的這一部分,有相當多的產品;撒克遜9.4是其中之一。

4

獲取不同節點的問題是如何確定兩個節點是不同的。這是XML中的一個複雜主題。如果重複節點具有相同的節點標識(即:它們引用相同的節點),那麼您可以使用像functx:distinct-nodes()這樣的功能。否則,您需要某種類型的散列來確定節點是否「足夠平等」以被視爲相等,或者使用deep-equal()進行比較,對於大型數據集來說性能較差。

如果兩個<author> s爲相等時,最後一個和名字是相同的,那麼你可以使用作爲concat(last,first)作爲哈希一樣簡單的東西,使用XPath得到不同的值:

$xml/author[index-of($xml/author/concat(last,first), concat(last,first))[1]] 

這仍然ISN」因爲你在每一步計算哈希,所以它會減慢大數據集的速度。爲了提高性能,有一兩件事你可以做的是預先計算對數據的哈希值,即:

<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) 
+1

不同值的很好的xpath表達式 – Jayy