user1004413
user1004413

Reputation: 2619

XQuery Distinct XML tag

I am trying create a XQuery to generate a following details of the xml tag used with the no. of occurrence

Book- 3 occurrence Article-2 occurrence conference - 1 occurrence

Is this possible? i've been trying but it does not work

<test>
   <book>
        <year>1992</year>
   ....
   </book>
   <article>
        <year>1992</year>
   ....
   </article>
   <conference>
        <year>1992</year>
   ....
   </conference>
   <article>
        <year>1992</year>
   ....
   </article>
   <book>
        <year>1992</year>
   ....
   </book>
   <book>
        <year>1992</year>
   ....
   </book>
</test>

Upvotes: 2

Views: 122

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243449

Use this pure and simple XPath 2.0 expression:

for $name in distinct-values(/*/*/name())
 return
   ($name, count(index-of(/*/*/name(),$name)),'&#xA;')

When this expression is evaluated against the provided XML document:

<test>
   <book>
        <year>1992</year>
   ....
   </book>
   <article>
        <year>1992</year>
   ....
   </article>
   <conference>
        <year>1992</year>
   ....
   </conference>
   <article>
        <year>1992</year>
   ....
   </article>
   <book>
        <year>1992</year>
   ....
   </book>
   <book>
        <year>1992</year>
   ....
   </book>
</test>

the wanted, correct result is produced:

 book 3
 article 2 
 conference 1 

Upvotes: 2

JLRishe
JLRishe

Reputation: 101682

Here is an approach that should work if the group by syntax is not supported in the XQuery you are using:

for $dn in distinct-values(for $x in (/test/*) 
                           return local-name($x))
let $count := count(/test/*[local-name() = $dn])
order by $count descending
return ($dn, "-", $count, "occurrence(s) ")

The result from this is:

book - 3 occurrence(s) article - 2 occurrence(s) conference - 1 occurrence(s)

Upvotes: 1

Vincent Biragnet
Vincent Biragnet

Reputation: 2998

From what I understand. Here is an "XQuery 3" solution :

for $x in (/test/*) 
    let $eltName := local-name($x)
    group by $eltName 
return ($eltName, "-",count($x), "occurrence(s) /")

For the XML provided, the result is :

conference - 1 occurrence(s) / book - 3 occurrence(s) / article - 2 occurrence(s) /

Upvotes: 0

Related Questions