2010-10-06 8 views
2

J'ai une base de données XML qui contient des éléments qui ont un ID. Ce sont tous uniques. Ils ont également un identifiant secondaire qui les relie à un objet similaire dans une autre base de données. Ce ne sont pas tous uniques.Xquery ID de duplicata

Existe-t-il un XQuery qui me permettrait d'identifier tous les ID non uniques? Je peux compter combien il y en a en utilisant distinct-values ​​(), mais cela ne permet pas d'identifier les ID qui ont des doublons!

Exemple XML: (chaque objet est contenu dans un fichier séparé dans la base de données eXist)

<object id="uniqueID123"> 
    <secondary identifier="nonUnique888"/> 
</object> 

<object id="uniqueID456"> 
    <secondary identifier="nonUnique888"/> 
</object> 

<object id="uniqueID789"> 
    <secondary identifier="Unique999"/> 
</object> 

Je voudrais identifier la chaîne dupliquée « nonUnique888 ».

+0

@ user320425: Semanticly c'est double de [ce] (http://stackoverflow.com/questions/133092/how-do-you-identify-duplicate -elements-in-an-xpath-20-sequence # 287360) car XQuery est un sur-ensemble de XPath. –

+0

Wow, $ vSeq [index-de ($ vSeq,.) [2]] est en effet une solution très élégante! Je n'ai pas réalisé que l'index-of() fonctionnait comme ça, trop habitué au style Java find-the-first. – Nick

+0

@ user320425: Bonne question (+1). Lisez ma réponse qui, je l'espère, contient la solution la plus courte. –

Répondre

3

La requête suivante renvoie tous les identificateurs non uniques:

let $sec := doc('source')/root/object/secondary 
for $id in distinct-values($sec/@identifier) 
where count($sec[@identifier eq $id]) gt 1 
return $id 
+0

A travaillé parfaitement, merci :) – Nick

2

Utilisation:

let $vSeq := /object/secondary/@identifier 
    return 
    $vSeq[index-of($vSeq,.)[2]] 

Lire l'explication here.

0

utiliser ce magasin de code dans le fichier xml

let $path:="/db/test/all.xml" 
let $a := xmldb:store($col,'adub.xml',<root></root>) 

let $sec := doc($path)//profile 
for $id in distinct-values($sec/mail) 
where count($sec[mail eq $id]) gt 1 
return 
update insert 
      <profile> 
       {$id} 
       </profile> 
    into doc($a)/root