user3111525
user3111525

Reputation: 5203

How to group elements based on attribute in xquery?

I have this xml:

<all>
    <a>
       <b x="i" al="kl"/>
       <b x="j" al="ml"/>
       <b x="k" al="jl"/>
       <b x="j" al="pl"/>
       <b x="j" al="il"/>
       <b x="i" al="dl"/>
    </a>
    <a>
       <b x="i1" al="kl"/>
       <b x="j2" al="ml"/>
       <b x="k3" al="jl"/>
       <b x="j2" al="pl"/>
       <b x="j2" al="il"/>
       <b x="i3" al="dl"/>
    </a>
</all>

What I really want to do is for each a I need to group element b by @x. So the result looks like:

<a x="j">
 <b x="j" l="ml"/>
 <b x="j" l="pl"/>
...
</a>
<a x="i">
  <b x="i" al="kl"/>
  <b x="i" al="dl"/>
</a>
...
...
...

Upvotes: 3

Views: 1233

Answers (2)

Dennis M&#252;nkle
Dennis M&#252;nkle

Reputation: 5071

If your processor supports XQuery 1.1 you can simply use group by:

let $all := 
  <all>
    <a>
       <b x="i" al="kl"/>
       <b x="j" al="ml"/>
       <b x="k" al="jl"/>
       <b x="j" al="pl"/>
       <b x="j" al="il"/>
       <b x="i" al="dl"/>
    </a>
    <a>
       <b x="i1" al="kl"/>
       <b x="j2" al="ml"/>
       <b x="k3" al="jl"/>
       <b x="j2" al="pl"/>
       <b x="j2" al="il"/>
       <b x="i3" al="dl"/>
    </a>
  </all>
for $a in $all/a
for $b in $a/b
let $x := string($b/@x)
group by $x
order by $x
return
  <a x="{$x}">
     {$b}
  </a>

You can execute this code on http://try.zorba-xquery.com/

Upvotes: 1

user357812
user357812

Reputation:

This XQuery:

element result {
   for $a in /all/a
   return for $x in ($a/b/@x)[index-of($a/b/@x,.)[1]]
          return element a {
                    $x,
                    $a/b[@x eq $x]
                 }
}

Output:

<result>
    <a x="i">
        <b x="i" al="kl"/>
        <b x="i" al="dl"/>
    </a>
    <a x="j">
        <b x="j" al="ml"/>
        <b x="j" al="pl"/>
        <b x="j" al="il"/>
    </a>
    <a x="k">
        <b x="k" al="jl"/>
    </a>
    <a x="i1">
        <b x="i1" al="kl"/>
    </a>
    <a x="j2">
        <b x="j2" al="ml"/>
        <b x="j2" al="pl"/>
        <b x="j2" al="il"/>
    </a>
    <a x="k3">
        <b x="k3" al="jl"/>
    </a>
    <a x="i3">
        <b x="i3" al="dl"/>
    </a>
</result>

Upvotes: 4

Related Questions