XQuery How can you add up values from similar XML structures with a unique identifier

XQuery How can you add up values from similar XML structures with a unique identifier



I have similiar XML structures eg.


<PLAYERS>
<PLAYER>
<NAME>Jack</NAME>
<SCORE>120</SCORE>
</PLAYER>
<PLAYER>
<NAME>Joe</NAME>
<SCORE>100</SCORE>
</PLAYER>
<PLAYER>
<NAME>Jane</NAME>
<SCORE>170</SCORE>
</PLAYER>
</PLAYERS>



and


<PLAYER>
<NAME>Joe</NAME>
<SCORE>40</SCORE>
</PLAYER>
<PLAYER>
<NAME>Jane</NAME>
<SCORE>20</SCORE>
</PLAYER>



I want to get the first data structure, but with the scores added up by the matching element NAME. For this example it would be:


NAME


<PLAYERS>
<PLAYER>
<NAME>Jack</NAME>
<SCORE>120</SCORE>
</PLAYER>
<PLAYER>
<NAME>Joe</NAME>
<SCORE>140</SCORE>
</PLAYER>
<PLAYER>
<NAME>Jane</NAME>
<SCORE>190</SCORE>
</PLAYER>
</PLAYERS>



As you can see, each name which is not present in the second data set should still be showed in the final result. I came up with a few ideas, but the FLOWR expression used in XQuery is a bit confusing for me. Thought about using two for loops.



Any solutions?




1 Answer
1



It is a grouping problem you can solve with group by clause https://www.w3.org/TR/xquery-31/#id-group-by:


group by


declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

declare option output:method 'xml';
declare option output:indent 'yes';


declare variable $players2 as element(PLAYER)* := (<PLAYER>
<NAME>Joe</NAME>
<SCORE>40</SCORE>
</PLAYER>,
<PLAYER>
<NAME>Jane</NAME>
<SCORE>20</SCORE>
</PLAYER>);

<PLAYERS>

for $players in (PLAYERS/PLAYER, $players2)
group by $name := $players/NAME
return
<PLAYER>

$players[1]/NAME,
<SCORE>

sum($players/SCORE)


</SCORE>

</PLAYER>

</PLAYERS>



https://xqueryfiddle.liberty-development.net/b4GWV5





Thank you, it works, but I have a question. What exactly does for $x in ($y, $z)? Is this like two for loops?
– Ian Fako
Aug 26 at 8:00


for $x in ($y, $z)





The expression (PLAYERS/PLAYER, $players2) simply forms the sequence (see w3.org/TR/xquery-31/#construct_seq) of the PLAYER elements in PLAYERS/PLAYER and in the variable $players2. The for $players in (PLAYERS/PLAYER, $players2) expression clause (see w3.org/TR/xquery-31/#id-xquery-for-clause) then simply binds the variable $players to that sequence constructed with (PLAYERS/PLAYER, $players2) so that the rest of the FLWOR expression, in this case the subsequent group by clause, works on the sequence bound to $players.
– Martin Honnen
Aug 26 at 8:52


(PLAYERS/PLAYER, $players2)


PLAYER


PLAYERS/PLAYER


$players2


for $players in (PLAYERS/PLAYER, $players2)


$players


(PLAYERS/PLAYER, $players2)


group by


$players






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)