2009-07-31 6 views
1

Ich möchte die Dokumente in einer Sammlung abrufen, die erfüllen, dass ein bestimmtes Element kein bestimmtes Kindelement hat. Zum Beispiel möchte ich aus den beiden "Dokumenten" unten Dokument 2 auswählen, da es das Element untergeordnet hat, aber Dokument 1, da dies nicht der Fall ist.Funktion zum Erreichen von "Element hat dieses Kind nicht"?

Doc 1:

<doc> 
<element> 
    <child/> 
</element> 
</doc> 

Doc2:

<doc> 
<element> 
    <other-child/> 
</element> 
</doc> 

Ich habe versucht, dies zu tun:

for $item in collection('/db/collection') 
where not($item//child) 
return $item 

Dies ist jedoch aus irgendeinem Grund nicht funktioniert. Ich habe auch verschiedene Kombinationen von exists, Sequenzfunktionen usw. ausprobiert, konnte aber nicht das gewünschte Ergebnis erzielen.

Um zu klären, der not($item//child) Test scheint nicht zu tun, was ich denke, es tun würde. Die obige Abfrage gibt jedes Dokument in meiner Sammlung zurück, ob es das Element enthält oder nicht. Die inverse funktioniert jedoch:

for $item in collection('/db/collection') 
where $item//child 
return $item 

Diese Abfrage liefert genau jene Dokumente, die das untergeordnete Element haben.

Was gibt?

+0

Das ist wirklich komisch. Wenn Sie statt dessen "count ($ item // child)" verwenden, welche Ausgabe erhalten Sie - gibt es welche mit 0? –

+0

Oh, und übrigens, welche XQuery-Implementierung wird verwendet? –

+1

Ich habe dies mit Saxon 9 (mit einer einfachen Sequenz von '' Knoten anstelle von 'Sammlung' jedoch) überprüft, und ich sehe die erwarteten Ergebnisse, nicht was Sie beschreiben. Es scheint, dass entweder Ihr tatsächlicher XML-Code komplizierter ist oder Ihre Abfrage nicht so geschrieben ist oder Ihre Implementierung fehlerhaft und/oder nicht konform ist. –

Antwort

0

Scheint ein Fehler in der XQuery-Engine von eXist (1.2.6) zu sein, wenn namespaced xml-Dokumente verwendet werden, da es auf Dokumenten ohne Namespace und auf dem neuesten svn-Snapshot funktioniert.
Bummer.

0

um den Fehler zu erhalten, wie etwa das für den Moment:

for $item in collection('/db/collection') 
return 
    if ($item//child) then 
    $item 
    else 
    () 
2

Ich glaube, Sie brauchen beide nicht() zu verwenden und exists() die gewünschten Ergebnisse zu erzielen. Also, ich glaube, Sie etwas tun wollen wie:

for $item in collection('/db/collection') return 
    if (not(exists($item//child))) then $item 
    else() 

über Ihren Namensraum Problem: Wenn Ihr Dokument ein Namespace verwendet, dann sollten Sie die richtige Namespace-Deklaration in der XQuery-Anweisung haben, wie declare namespace ns="some_uri";

Hoffnung das hilft.
-tjw