Just out of interest, if I was using a pre-XQuery 3.0 processor, would there have been any other approach than iterating over distinct-values?
...nope. The query might be evaluated faster if you bin all target elements to a variable...
let $pii := /dataset/item/pii/string() for $val in distinct-values($pii)[count($pii[. = $val]) > 1] return <duplicate>{$val}</duplicate>
...but this depends on the underlying query processor.
Thanks also for the pointer about using 'null'. The Basex query editor seemed to approve it when I tried it once, and the habit stuck ;-)
"null" is a valid XQuery expresion. If you have a database opened, this query will give you all documents in the database with the root element <null>...</null>.