[英]Why is the XQuery expression returning the wrong element count?
我想返回的每时间表L1和L0项目的数量,并警告的数量,也按计划。
这实际上是一个“数量如果”的情况。
我尝试了以下XQuery,它可以很好地计算L1,L0和警告,但会计算所有警告,而不是仅value = "yes"
警告。
xquery version "3.0";
let $nl := " "
let $quote := """
let $pipe := "|"
let $nodecount := 0
for $profiles in doc("maik test.xml")/PROFILE
for $schedule in $profiles/SCHEDULE
let $schedulename := $schedule/@name
group by $schedulename
return ($nl,
$schedulename, $pipe, "L0 count:", count($schedule/L0),
$pipe, "L0 Warnings:", count($schedule/L0/ATTRIBUTE[@NAME = "Warnings"]/VALUE/string() = "Yes"),
$pipe, "L1 count:", count($schedule/L0/L1),
$pipe, "L1 Warnings:", count($schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE/string() = "Yes"))
示例XML:
<?xml version="1.0" encoding="UTF-8"?>
<PROFILE name="profile1">
<SCHEDULE name="schedule1">
<L0>
<ATTRIBUTE NAME="Warnings">
<VALUE>No</VALUE>
</ATTRIBUTE>
<L1>
<ATTRIBUTE NAME="Warnings">
<VALUE>No</VALUE>
</ATTRIBUTE>
</L1>
<L1>
<ATTRIBUTE NAME="Warnings">
<VALUE>No</VALUE>
</ATTRIBUTE>
</L1>
<L1>
<ATTRIBUTE NAME="Warnings">
<VALUE>Yes</VALUE>
</ATTRIBUTE>
</L1>
<L1></L1>
</L0>
<L0>
<ATTRIBUTE NAME="Warnings">
<VALUE>No</VALUE>
</ATTRIBUTE>
<L1></L1>
</L0>
</SCHEDULE>
<SCHEDULE name="schedule2">
<L0>
<L1></L1>
<L1></L1>
<L1></L1>
<L1></L1>
</L0>
<L0>
<L1></L1>
</L0>
<L0>
<L1></L1>
<L1></L1>
<L1></L1>
</L0>
</SCHEDULE>
</PROFILE>
实际上,你也在计算错误的L0警告 - 但是偶然的,它们的结果是正确的。
尝试返回$schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE/string() = "Yes"
(没有聚合)以了解出现了什么问题。 此子查询返回一个布尔值,如果左侧的任何值与右侧的任何值匹配(在这种情况下,只是一个值),则该值为true。 换句话说,如果任何警告为Yes
是Yes
,则该语句为true
。 如果根本不匹配,则返回false
。 在XQuery中, =
有一个set-semantics。
现在,你计算结果的数量,无论布尔结果是什么,它都是1
。
总结一下,代码中有两个问题:
=
,而是使用eq
(还有lq
, gq
, le
, ge
和ne
代表<
, >
, <=
, >=
, !=
)。 L0警告的正确子查询将是
count($schedule/L0/ATTRIBUTE[@NME = "Warnings"]/VALUE[string() eq "Yes"])
类似的L1警告:
count($schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE[string() eq "Yes"])
在这里非常完整:这是现在可以正常工作的XQuery:
xquery version "3.0";
let $nl := " "
let $pipe := "|"
for $profiles in doc("maik test.xml")/PROFILE
for $schedule in $profiles/SCHEDULE
let $schedulename := $schedule/@name
group by $schedulename
return ($nl,
$schedulename, $pipe, "L0 count:", count($schedule/L0),
$pipe, "L0 Warnings:", count($schedule/L0/ATTRIBUTE[@NAME = "Warnings"]/VALUE[string() eq "Yes"]),
$pipe, "L1 count:", count($schedule/L0/L1),
$pipe, "L1 Warnings:", count($schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE[string() eq "Yes"]))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.