XQuery 3:统计文档中元素名称的出现次数

XQuery 3: Count occurrences of element names across document

基于

我将 运行 使用 BaseX 9.5.2 进行此查询。

给定数据

<?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>

我想生成这样的 table

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

我可以通过

获得唯一元素名称的列表
let $sep := '&#09;' (: tab :)

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

let $currname := name(
  $elems
)

group by $currname

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

title
author

我想我想用count(),但是我不知道怎么说我想算父本。在我上面提到的回答问题中,要计数的元素名称在查询中是硬编码的。在这种情况下,我使用通配符。

由于您已有的分组,count($elems) 将在 return 子句中具有正确的值。

我认为您最初使用 let $sep 会导致问题,我建议的分组 count($elems)https://xqueryfiddle.liberty-development.net/bFDbxm7 对我来说很好用,我已经移动了 $sep声明的变量。

我正在使用 BaseX v.9.5.2

请尝试以下 XQuery。

XQuery

xquery version "3.1";

declare context item := document {
<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>
};

<root>
{
  let $title := count(./bookstore/book/title)
  let $author := count(distinct-values(./bookstore/book/author))
  return <r>
    <title>{$title}</title>
    <unique_author_count>{$author}</unique_author_count>
  </r>
}
</root>

XQuery #2

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

declare option output:method 'text';
declare option output:item-separator '&#10;';
    
declare context item := document {
<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>
};

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

for $elems in ./bookstore/book/*
let $currname := local-name($elems)
group by $currname
return string-join(($currname, count(distinct-values($elems[local-name()=$currname])),$sep))