5

Let's say I have the following XML:

<info>
    <channel>
        <A>
          <X>
            <title>title1</title>
          </X>
          <Y value="20"/>
        </A>
    </channel>
    <channel>
        <A>
          <X>
            <title>title1</title>
          </X>
          <Y value="20"/>
        </A>
        <A>
          <X>
            <title>title2</title>
          </X>
          <Y value="20"/>
        </A>
    </channel>
</info>

and the following XQuery

{
for $A in doc('test.xml')//A
let $TITLE := $A/X/title
where string($A/Y/value) > 20
return
  string($TITLE)
}

this, of course, outputs:

title1
title1
title2

How can I use distinct-values in order to remove duplicates? I wonder because for essentially only gives me one item per iteration and I can't call distinct-values on $A. Or is there any other way to remove duplicate output?

The problem is that I need to refer to another node, so basically calling distinct-values(doc...) doesn't work, as it doesn't return nodes.

slhck
  • 36,575
  • 28
  • 148
  • 201

1 Answers1

5

UPDATE

to filter duplicate nodes, use a variation of the xpath from this answer:

//A[index-of(//A/X/title, X/title)[1]]

this gives you all the As with different titles.

you can expand this xpath expression to also filter on Y - no need for XQuery FLWOR.

UPDATE END

apply the distinct-values to the xpath expression over which you want to iterate:

for $title in distinct-values(doc('test.xml')//A/X/@title)
return string($title)

or just

distinct-values(doc('test.xml')//A/X/@title)
Community
  • 1
  • 1
ax.
  • 58,560
  • 8
  • 81
  • 72
  • It didn't really work. It selects some nodes, but I can't figure out which ones. There are no duplicates, but some are missing completely. I updated my question again. – slhck Mar 14 '11 at 08:49
  • Ok, it seems that it doesn't work when the `A` element is not the root! – slhck Mar 14 '11 at 08:58
  • Got it figured out. You might want to update your answer to reflect those changes, but in the end it comes to first iterating over the `channel` elements and then a variation of your line: `for $A in $CHANNEL/A[index-of(//$CHANNEL/A/X/title, X/title)[1]]` – slhck Mar 14 '11 at 09:07