[XQuery] Except or intersect won't work.


I’m using Tamino 4.2.1 to develop a conference management system for my university, and I’ve encountered a strange problem.

A user can have several places of work (for example, an enterpreneur who reads lectures), and to prevent him or her from entering the same place of work twice, I need to present him or her with a choice of available organisations that doesn’t include those he or she already works for.

After searching through Tamino help files and W3C XQuery reference, I found a function I could use. “Except”

The query looks like this:

input()/organisation/@org-id except input()/person[@person-id='oo']/workplace/@org-id

Or this:

(for $o in input()/organisation
return $o/@org-id)
(for $w in input()/person/workplace
where $w/../@person-id='oo'
return $w/@org-id)

Or this:

let $o := input()/organisation/@org-id
let $w := input()/person[@person-id='oo']/workplace/@org-id
return $o except $w

But it won’t work!
$o returns

      <xq:attribute org-id="mesi"/>
      <xq:attribute org-id="kvz"/>
      <xq:attribute org-id="sag"/>

$w returns

      <xq:attribute org-id="mesi"/>
      <xq:attribute org-id="kvz"/>

Union operation works perfectly and produces a set of five values, but except returns not one value, “sag”, but allt hree of them. Intersect returns and empty result set.
I’m completely baffled by this behavior. Am I doing something wrong? Or is ‘except’ not implemented in Tamino 4.2.1?

In the W3C’s documentation on union, intersect, and except it says:

I think this is why it isn’t working like you expect: the sequence of nodes selected by the second expression come from different documents than the ones in the first expression, so even though the values are the same they are not the identical nodes and nothing gets excluded.

I’d try something like this:

let $w := input()/person[@person-id='oo']/workplace/@org-id
for $o in input()/organisation/@org-id
where not($o/text() = $w/text())
return $o

(If you compare a single value to a sequence, it returns true if any of the items in the sequence would return true.)

Thanks, I’ll give it a try.

At first it didn’t work, but when I removed /text() it finally produced the results I wanted.
Thanks a lot!

Version 4.2 is quite outdated. Please use version 4.4