gpt4 book ai didi

xquery - 为什么这个 XQuery 过滤器会返回不需要的元素?

转载 作者:行者123 更新时间:2023-12-01 12:29:14 27 4
gpt4 key购买 nike

我正在使用实现 XQuery 3.1 的 BaseX 8.4.1

我正尝试在 XQuery 中做一些非常基本的事情,但我似乎无法弄明白。

我创建了一些示例数据来说明我正在尝试做的事情。我的数据集看起来像这样。它是一个简单的嵌入式结构。有几天,每天都有一些事件,事件有成员。

数据

<root>
<day>
<name>1</name>
<event>
<name>1</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>2</name>
<member>C</member>
</event>
</day>
<day>
<name>2</name>
<event>
<name>3</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>4</name>
<member>C</member>
</event>
</day>
<day>
<name>3</name>
<event>
<name>5</name>
<member>C</member>
</event>
</day>
</root>

我想做的是获取成员列表,并为每个成员获取他们举办事件的日期列表,以及他们举办的事件。所以结果应该是这样的:

期望的结果

<member>
<name>A</name>
<day>
<name>1</name>
<event>
<name>1</name>
<member>A</member>
<member>B</member>
</event>
</day>
<day>
<name>2</name>
<event>
<name>3</name>
<member>A</member>
<member>B</member>
</event>
</day>
</member>
<member>
<name>B</name>
<day>
<name>1</name>
<event>
<name>1</name>
<member>A</member>
<member>B</member>
</event>
</day>
<day>
<name>2</name>
<event>
<name>3</name>
<member>A</member>
<member>B</member>
</event>
</day>
</member>
<member>
<name>C</name>
<day>
<name>1</name>
<event>
<name>2</name>
<member>C</member>
</event>
</day>
<day>
<name>2</name>
<event>
<name>4</name>
<member>C</member>
</event>
</day>
<day>
<name>3</name>
<event>
<name>5</name>
<member>C</member>
</event>
</day>
</member>

为此,我尝试了以下 XQuery:

我尝试了什么

for $member in distinct-values(//member)
return
<member>
<name>{$member}</name>
{for $day in //day where $day/event/member = $member
let $event := $day/event where $event/member = $member
return
<day>
{$day/name}
{$event}
</day>}
</member>

但是,这不应用过滤。因此,我为他们不是成员的成员保留所有事件:

我得到了什么

<member>
<name>A</name>
<day>
<name>1</name>
<event>
<name>1</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>2</name>
<member>C</member>
</event>
</day>
<day>
<name>2</name>
<event>
<name>3</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>4</name>
<member>C</member>
</event>
</day>
</member>
<member>
<name>B</name>
<day>
<name>1</name>
<event>
<name>1</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>2</name>
<member>C</member>
</event>
</day>
<day>
<name>2</name>
<event>
<name>3</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>4</name>
<member>C</member>
</event>
</day>
</member>
<member>
<name>C</name>
<day>
<name>1</name>
<event>
<name>1</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>2</name>
<member>C</member>
</event>
</day>
<day>
<name>2</name>
<event>
<name>3</name>
<member>A</member>
<member>B</member>
</event>
<event>
<name>4</name>
<member>C</member>
</event>
</day>
<day>
<name>3</name>
<event>
<name>5</name>
<member>C</member>
</event>
</day>
</member>

当然,这应该很容易,不是吗?

最佳答案

这是一个非常小的问题。您想要过滤事件,并将 $events 定义为 $day 的所有事件的序列。然后,您使用 = 运算符进行过滤,该运算符具有设置的语义——如果左侧的任何项目(所有 当天的事件成员)等于任何项目在右侧(当前 $member),where 子句的计算结果为 true

改为循环处理事件。

for $member in distinct-values(//member)
return
<member>
<name>{$member}</name>
{for $day in //day where $day/event/member = $member
(: for instead of let :)
for $event in $day/event where $event/member = $member
return
<day>
{$day/name}
{$event}
</day>}
</member>

使用谓词而不是 where 子句通常会使代码更易于阅读并且嵌套的显式循环更少。这是一个清理过的例子:

for $member in distinct-values(//member)
return
<member>{
<name>{ $member }</name>,
for $day in //day[event/member = $member]
return
<day>{
$day/name,
$day/event[member = $member]
}</day>
}</member>

关于xquery - 为什么这个 XQuery 过滤器会返回不需要的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35994114/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com