Reputation: 85
Input:
<relations>
<relation>
<isIdenticalInternationalStandardOf id="AssetID" metadataStatus="Publishable">1234</isIdenticalInternationalStandardOf>
<isIdenticalInternationalStandardOf id="PrimaryDesignator">abc</isIdenticalInternationalStandardOf>
</relation>
<relation>
<isIdenticalRegionalStandardOf id="AssetID" metadataStatus="Publishable">1234</isIdenticalRegionalStandardOf>
<isIdenticalRegionalStandardOf id="PrimaryDesignator">abc</isIdenticalRegionalStandardOf>
</relation>
<relation>
<supersededBy id="AssetID" metadataStatus="Publishable">5647</supersededBy>
<supersededBy id="PrimaryDesignator">pqr</supersededBy>
</relation>
<relation>
<replacedBy id="AssetID" metadataStatus="Publishable">1234</replacedBy>
<replacedBy id="PrimaryDesignator">abc</replacedBy>
</relation>
<relation>
<supersededBy id="AssetID" metadataStatus="Publishable">1234</supersededBy>
<supersededBy id="PrimaryDesignator">xyz</supersededBy>
</relation>
<relation>
<isIdenticalInternationalStandardOf id="AssetID" metadataStatus="Publishable">1234</isIdenticalInternationalStandardOf>
<isIdenticalInternationalStandardOf id="PrimaryDesignator">abc</isIdenticalInternationalStandardOf>
</relation>
<relation>
<isIdenticalInternationalStandardOf id="AssetID" metadataStatus="Publishable">1234</isIdenticalInternationalStandardOf>
<isIdenticalInternationalStandardOf id="PrimaryDesignator">abc</isIdenticalInternationalStandardOf>
</relation>
</relations>
I could able to find duplicate from Input, here is code:
let $data := $each-search-copy/relations
let $map := map:map()
let $uniqueList :=
for $outer at $i in $data/relation
for $inner at $j in $data/relation
where $i ne $j
return
if(fn:deep-equal($outer, $inner)) then
if(fn:exists(map:get($map, xs:string($j)))) then () else map:put($map, xs:string($i), xs:string($j))
else ()
let $duplicate :=
for $each at $i in $data/relation
return
if(fn:exists(map:get($map, xs:string($i))))
then (
fn:string-join((xdmp:quote($each), " "), "|")
) else ()
finding duplicate node is done, Now I want to write update transaction query which will keep only unique list of nodes. if multiple occurrence is there then it should get deleted.
with the help of MAP construct I could delete if duplicate is there but not multiple occurrences.
Upvotes: 1
Views: 169
Reputation: 66783
You can remove the nodes by invoking the xdmp:node-delete()
function for each of the nodes that you want to remove.
You can identify those duplicate elements a little more simply and succinctly in a single for loop, and a where
clause that tests whether the relationship
element is deep-equal()
to any of it's relationship
siblings, excluding the current relationship
element being processed in the for loop by ensuring that the generate-id()
values (guaranteed to be the same for the same node) are not equal:
let $all-relations := $each-search-copy/relations/relation
return
for $relation in $all-relations
where $all-relations[fn:deep-equal(., $relation) and generate-id(.) ne generate-id($relation)]
return xdmp:node-delete($relation)
Upvotes: 2
Reputation: 433
Instead of deleting the duplicates, you can just rebuild the de-duplicated list and do a single replacement. e.g. iterate through the list and output every relation that hasn't been seen before.
let $uniqueList :=
for $outer at $i in $data/relation
where every $inner in ($data/relation)[1 to $i - 1]
satisfies fn:not(fn:deep-equal($inner, $outer))
return $outer
return xdmp:node-replace($data, <relations>{ $uniqueList }</relations>)
Upvotes: 0