为什么 XQuery 表达式返回错误的元素计数?
Why is the XQuery expression returning the wrong element count?
我想要 return 每个计划的 L1 和 L0 项目的数量 和 还有警告的数量,也是每个计划。
其实是"count if"的情况。
我尝试了以下 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 警告 -- 但碰巧它们的结果是正确的。
尝试 return $schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE/string() = "Yes"
(没有聚合)以了解哪里出了问题。此子查询 return 是一个布尔值,如果左侧的任何值与右侧的任何值匹配(在本例中,只有一个值),则该布尔值为真。换句话说,如果 any 的警告是 Yes
,则语句得到 true
。如果 none 完全匹配,则 false
被 returned。在 XQuery 中,=
有一个集合语义。
现在,您正在计算结果的数量,无论布尔结果是什么,结果都是 1
。
总结一下,代码中有两个问题:
- 比较单个元素不要用
=
,用eq
代替(还有lq
、gq
、le
, ge
和 ne
for <
, >
, <=
, >=
, !=
).
- 不要比较结果序列(这将 return 一个布尔值),而是使用谓词对其进行过滤。
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"]))
我想要 return 每个计划的 L1 和 L0 项目的数量 和 还有警告的数量,也是每个计划。
其实是"count if"的情况。
我尝试了以下 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 警告 -- 但碰巧它们的结果是正确的。
尝试 return $schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE/string() = "Yes"
(没有聚合)以了解哪里出了问题。此子查询 return 是一个布尔值,如果左侧的任何值与右侧的任何值匹配(在本例中,只有一个值),则该布尔值为真。换句话说,如果 any 的警告是 Yes
,则语句得到 true
。如果 none 完全匹配,则 false
被 returned。在 XQuery 中,=
有一个集合语义。
现在,您正在计算结果的数量,无论布尔结果是什么,结果都是 1
。
总结一下,代码中有两个问题:
- 比较单个元素不要用
=
,用eq
代替(还有lq
、gq
、le
,ge
和ne
for<
,>
,<=
,>=
,!=
). - 不要比较结果序列(这将 return 一个布尔值),而是使用谓词对其进行过滤。
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"]))