Prasadika
Prasadika

Reputation: 927

How to print unique values in xquery

I have the following XQuery function with me.

declare function local:format($input as element() *) as element() *{

for $v in

$input
return if
 (((for $x in $input return $x)/@one=$v/@two)   and ((for $y in $input return $y)/@two=$v/@one))
        then
        (   





         )

        else {$v}


};

The input to the above function is :

**  <pair two="IN011" one="IN007">  David Emma  </pair>  **


   **   <pair two="IN007" one="IN011">   Emma David    </pair>  **

But the output I want is :

**    <pair two="IN011" one="IN007">   David Emma   </pair>  **

or else:

**    <pair two="IN007" one="IN011">   Emma David   </pair>  **

That is, I want it to be printed only once.

The functionality of the above function should be something like that. But, it's incomplete.I tried every possible way. Please help to get the output I've mentioned above

Upvotes: 0

Views: 371

Answers (1)

wst
wst

Reputation: 11771

What you want to do is normalize the values in your source sequence and return the distinct values based on the normalized strings:

declare function local:normalize(
  $label as xs:string
) as xs:string
{
  string-join(
    for $t in tokenize($label, '\s+')
    order by $t 
    return $t)
};

let $pairs := (<pair two="IN011" one="IN007">  David Emma  </pair>,
  <pair two="IN007" one="IN011">   Emma David    </pair>)
let $pairs-normalized :=
  for $p in $pairs
  return element pair {
    $p/@*,
    attribute hash { local:normalize($p) },
    $p/node()
  }
return $pairs-normalized[index-of($pairs-normalized/@hash, @hash)[1]]

=> <pair two="IN011" one="IN007" hash="DavidEmma"> David Emma </pair>

Another way of doing it is using distinct-values:

for $d in distinct-values($pairs-normalized/@hash)
return ($pairs-normalized[@hash = $d])[1]

Upvotes: 1

Related Questions