1
votes

I have this piece of XML-code:

<player name="John" points="50">
  <game points="5">Beans</game>
  <game points="40">Cucumbers</game>
  <game points="50">Tomatos</game>
</player>

What I want to do is to get this piece, but only with those games where number of points (attribute of "game") is equal to points which is attribute of "player". Thus, considering above example, I should get next XML-piece:

<player name="John" points="50">
  <game points="50">Tomatos</game>
</player>

I write following XQuery:

for $a in doc("ex.xml")
where $a/xs:int(@points)=$a/game/xs:int(@points)
return $a

But I don't get any result. Could you please help me?

1

1 Answers

3
votes

You cannot modify/filter a subtree by selecting parts of it (if not using XQuery Update). You will have to reconstruct the XML instead.

element player {
  /player/@*,
  /player/game[@points=/player/@points]
}

The first line creates a new element, the second line adds the attributes again, and the third line all games that fulfill the points condition.

If you've got multiple players in a document which you need to loop over, the code would look like that:

for $player in /player
return element player {
  $player/@*,
  $player/game[@points=$player/@points]
}

Now, we do not start all queries at the root level, but use the $player as context instead.

Using XQuery Update (if supported by your XQuery processor), you could also do something like this (actually not changing the original document, but only a copy):

copy $result := .
modify delete node $result//game[../@points != @points]
return $result