Function to achieve “Element does not have this child”?
-
06-07-2019 - |
Question
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?
Solution 2
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.
OTHER TIPS
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
To get around the bug, how about this for the moment:
for $item in collection('/db/collection')
return
if ($item//child) then
$item
else
()