tags:

views:

35

answers:

3

I want to retrieve the documents in a collection which satisfy that a given element does not have a specific child element. For example, from the two "documents" below, I want to select doc 2, since it has the element child, but doc 1, since it does not.

Doc 1:

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

Doc2:

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

I tried doing this:

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

However, this does not work for some reason. I also tried various combinations of exists, sequence functions etc, but couldn't get the result I want.

To clarify, the not($item//child) test does not seem to do what I think it'd do. The above query returns every document in my collection, wether it has the element or not. The inverse works, however:

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

This query returns exactly those documents which have the child element.

What gives?

A: 

Seems to be a bug in eXist's XQuery engine (1.2.6) when using namespaced xml documents, since it works on documents without a namespace, and on the latest svn snapshot.
Bummer.

carlpett
A: 

To get around the bug, how about this for the moment:

for $item in collection('/db/collection') 
return 
  if ($item//child) then
    $item
  else 
    ()
Pabs
A: 

I think you need to use both not() and exists() to achieve your desired results. So, I think you want to do something like:

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

About your namespace issue: if your document uses a namespace, then you should have the proper namespace declaration in your XQuery statement, like declare namespace ns="some_uri";

Hope this helps.
-tjw

Travis J Webb