1
votes

I have XML as follows:

<Root>  
    <Inv><Id>1</Id><Name>John</Name></Inv>
    <Inv><Id>2</Id><Name>Tom</Name></Inv>
    <Inv><Id>1</Id><Name>John</Name></Inv>
    <Inv><Id>4</Id><Name>Harry</Name></Inv>

</Root>

Want to retrieve only unique nodes using XQUERY.

Could you please guide?

2
@NaveedS - Thank you Naveed. What if I have more than 1 <Root> tags saved in Database and I want to retrive it. Thus I have one <Root> tag saved in one row and other in second row. - Puru
Hi, Its not working for me, could you help me? - Puru
Actually I'm new to xquery and I couldn't exactly identify the proper solution to your problem. That's why I suggested the link instead of posting the answer. Let me try to figure out something. Not sure whether I can help you. Sorry. - Naveed S
What is your criteria for "unique nodes"? Do you mean that you want a distinct list of <Inv> elements? Can you describe your criteria and show an example of the output that you are trying to generate from the sample input? - Mads Hansen

2 Answers

1
votes

The following XQuery produces a distinct list of <Inv> elements by performing a deep-equal() comparison of the sequence of <Inv> elements:

let $invSequence := /Root/Inv
(:
  For each position(),
  return the <inv> element who's position is equal to the current number,
  and who's previous siblings are not deep-equal() 
:)
for $pos in (1 to count($invSequence))
return $invSequence[$pos] 
                    [not(some $inv in $invSequence[position() < $pos] 
                           satisfies deep-equal(., $inv))]

The result:

<Inv>
   <Id>1</Id>
   <Name>John</Name>
</Inv>
<Inv>
   <Id>2</Id>
   <Name>Tom</Name>
</Inv>
<Inv>
   <Id>4</Id>
   <Name>Harry</Name>
</Inv>
0
votes

If you know the structure and only have two child elements of <Id> and <Name>, then you could group by those elements and select the first one from the group:

for $inv in /Root/Inv
  let $id := $inv/Id
  let $name := $inv/Name
  group by $id, $name
return $inv[1]