2013-05-11 27 views
-2

將函數distinct-values()應用於節點序列時,它會返回一個值序列而不是一系列節點。如何在XQuery中獲取不同的節點?

請有人向我解釋XQuery數據模型的哪些特性使得難以直接在一系列節點上消除重複值?

另外,如何將這個值序列轉換回節點序列?

我查看了我的XML/XQuery筆記,並在沒有找到明確信息的情況下搜索了互聯網。

回答

4

在XQuery中,每個節點都是不同的(它有一個內部唯一的節點ID)。如果你想比較節點,你將不得不深入比較它們的值。沒有預定義的功能,但由於這是一個常見問題,因此FunctX包含一個,functx:distinct-deep()。它依賴於functx:is-node-in-sequence-deep-equal(),所以你也需要這個。

declare namespace functx = "http://www.functx.com"; 
declare function functx:distinct-deep 
    ($nodes as node()*) as node()* { 

    for $seq in (1 to count($nodes)) 
    return $nodes[$seq][not(functx:is-node-in-sequence-deep-equal(
          .,$nodes[position() < $seq]))] 
} ; 
declare function functx:is-node-in-sequence-deep-equal 
    ($node as node()? , 
    $seq as node()*) as xs:boolean { 

    some $nodeInSeq in $seq satisfies deep-equal($nodeInSeq,$node) 
} ; 

另外,您可以import the whole FunctX module,但這可以根據您的XQuery解釋減慢執行了很多。


如果你不想堅持FunctX,你需要搜索的所有不同的值,併爲每個找到的第一個元素(所以沒有任何之前的部分之一)和比較data()到不同的值。

for $value in distinct-values(//data()) 
return //*[data() = $value][every $preceding in preceding::node() satisfies name() != $preceding/name()] 

最後,這和上面的FunctX函數做的一樣。您可以對某些部分使用其他結構,但不能省略任何這些步驟。

+0

嗨仁!感謝你的及時回覆。只是爲了確認:無論如何,每個節點都是無用的,所以應用函數distinct-value是有問題的。我需要比較節點以查看它們是否是唯一的,即不同的,但是在XQuery中沒有預定義的工具來執行此操作。請問你能更清楚地知道如何將一系列值重新轉換成一系列節點?謝謝M – MafioSol 2013-05-11 21:46:29

+1

請介紹一下你的_real_問題。我不認爲你必須解決的問題是獲得不同的節點,但需要這樣做。提供一些輸入和預期輸出使得理解您的問題變得更容易。請編輯你的問題。也許還請閱讀[如何提供SSCCE](http://sscce.org/)。你越具體,你就越有可能和更快得到你需要的答案。 – 2013-05-11 21:51:07

+0

再次簡斯!我真正的問題如下:首先,當將函數distinct-values應用於一系列節點時,它會返回一系列值而不是一系列節點。簡要解釋XQuery數據模型的哪個特性使得難以直接在一系列節點上消除重複值。其次:你如何將這個值的序列轉換回節點序列? 謝謝 – MafioSol 2013-05-11 21:57:09