为什么XQuery表达式返回错误的元素数?

Mai*_*aik 4 xml xquery count xml-parsing xquery-3.0

我想返回的每时间表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"))
Run Code Online (Sandbox Code Playgroud)

示例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>
Run Code Online (Sandbox Code Playgroud)

Jen*_*rat 5

实际上,你也在计算错误的L0警告 - 但是偶然的,它们的结果是正确的.

尝试返回$schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE/string() = "Yes"(没有聚合)以了解出现了什么问题.此子查询返回一个布尔值,如果左侧的任何值与右侧的任何值匹配(在这种情况下,只是一个值),则该值为true.换句话说,如果有任何警告Yes,则语句得到true.如果完全没有匹配,false则返回.在XQuery中,=有一个set-semantics.

现在,你计算结果的数量,无论布尔结果是什么,都是1.

总结一下,代码中有两个问题:

  • 不要使用=,如果你想比较单一的元素,使用eq替代(也有lq,gq,le,gene<,>,<=,>=,!=).
  • 不要比较结果序列(将返回布尔值),而是使用谓词对其进行过滤.

L0警告的正确子查询将是

count($schedule/L0/ATTRIBUTE[@NME = "Warnings"]/VALUE[string() eq "Yes"])
Run Code Online (Sandbox Code Playgroud)

类似的L1警告:

count($schedule/L0/L1/ATTRIBUTE[@NAME = "Warnings"]/VALUE[string() eq "Yes"])
Run Code Online (Sandbox Code Playgroud)