Search code examples
xmlgroupingxquerycountingbasex

XQuery 3: Count occurrences of element names across document


Building on Count number of elements with same tag

I will be running this query with BaseX 9.5.2.

Given the data

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book category="COOKING">
        <title lang="en">Everyday Italian</title>
        <author>Giada De Laurentiis</author>
    </book>
    <book category="CHILDREN">
        <title lang="en">Harry Potter</title>
        <author>J K. Rowling</author>
    </book>
    <book category="WEB">
        <title lang="en">XQuery Kick Start</title>
        <author>James McGovern</author>
        <author>Per Bothner</author>
        <author>Kurt Cagle</author>
        <author>James Linn</author>
        <author>Vaidyanathan Nagarajan</author>
    </book>
    <book category="WEB">
        <title lang="en">Learning XML</title>
        <author>Erik T. Ray</author>
    </book>
</bookstore>

I would like to generate a table like this

+----------+--------------+
|          |              |
| Element  | total_count  |
+----------+--------------+
|          |              |
| title    | 4            |
+----------+--------------+
|          |              |
| author   | 8            |
+----------+--------------+

I can get a list of the unique element names with

let $sep := '&#09;' (: tab :)

for $elems in doc(
  'books'
)/bookstore/book/*

let $currname := name(
  $elems
)

group by $currname

return string-join(
       (
        $currname
       ),
       $sep
)

That is,

title
author

I think I want to use count(), but I'm not sure how to say that I want to count the parent books. In my answered question mentioned above, the element name to count was hard-coded in the query. In this case, I'm using a wildcard.


Solution

  • Due to the grouping you already have, count($elems) will have the right value in the return clause.

    I think you original use of the let $sep is causing problems, the grouping count($elems) I suggested works fine for me at https://xqueryfiddle.liberty-development.net/bFDbxm7 where I have moved the $sep to a declared variable.