我正在使用XQuery来分析具有相同XML结构的两组测试结果。下面的函数创建了一组新元素,这些元素是两个结果集的测试用例的单独比较。对于每个测试用例,两组之间应该存在1-1关系,但我的代码有时会产生8次比较,我无法弄清楚原因!
这是我的输入XML,用于具有不同数据的两个集合(例如缩写):
<tests>
<test-group name="TestA">
<test-case name="CaseA1" success="true"/>
<test-case name="CaseA2" success="false"/>
<test-case name="CaseA3" success="true"/>
</test-group>
<test-group name="TestB">
<test-case name="CaseB1" success="false"/>
<test-case name="CaseB2" success="false"/>
<test-case name="CaseB3" success="true"/>
</test-group>
<test-group name="TestC">
<test-case name="CaseC1" success="false"/>
<test-case name="CaseC2" success="false"/>
<test-case name="CaseC3" success="true"/>
</test-group>
</tests>
示例输出:
<test-state delta1="15" delta2="false" isPass="true" fixture="TestA" case="CaseA1"/>
<test-state delta1="12" delta2="true" isPass="false" fixture="TestA" case="CaseA1"/>
<test-state delta1="5" delta2="false" isPass="true" fixture="TestA" case="CaseA1"/>
<test-state delta1="15" delta2="false" isPass="true" fixture="TestC" case="CaseC1"/>
<test-state delta1="12" delta2="true" isPass="false" fixture="TestC" case="CaseC1"/>
<test-state delta1="5" delta2="false" isPass="true" fixture="TestC" case="CaseC1"/>
这是我的Xquery(例如修改):
declare function app:runReport() {
let $new-run := collection('collection1')
let $old-run := collection('collection2')
return
<report>
{
for $new-case in $new-run//test-case,
$old-case in $old-run//test-case
where $new-case/@name = $old-case/@name and $new-case/../@name = $old-case/../@name
return
let $new-msg := xs:string($new-case/message)
let $old-msg := xs:string($old-case/message)
let $new-len := string-length($new-msg)
let $old-len := string-length($old-msg)
let $msg-dif := $new-len - $old-len
let $delta1 := fn:compare(xs:string($new-case/@success),xs:string($old-case/@success)) = 0
let $delta2 := abs($msg-dif)
return
<test-state
delta1="{$delta1}"
delta2="{$delta2}"
isPass="{$new-case/@success}"
fixture="{$new-case/../@name}"
case="{$new-case/@name}"
path="unknownPath"/>
}
</report>
};
在我看来,它对$ case-case和$ case之间的每个组合进行了排列,但我不明白为什么。我会尝试过滤掉重复的内容,但它们不是完全相同的,它似乎有时使用$ old-case代替$ new-case。
答案 0 :(得分:1)
在我看来,它对$ new-case和$ old-case之间的每个组合进行了排列
凭借for
的结构,这正是正在发生的事情。例如:
for $x in (1, 2, 3), $y in ('a', 'b', 'c')
return <z>{$x, $y}</z>
=&GT;
<z>1 a</z>
<z>1 b</z>
<z>1 c</z>
<z>2 a</z>
<z>2 b</z>
<z>2 c</z>
<z>3 a</z>
<z>3 b</z>
<z>3 c</z>
相反,您可以查找匹配的旧测试:
for $new-case in $new-run//test-case
let $old-case := $old-run//test-case[@name = $new-case/@name]
return
...
答案 1 :(得分:1)
猜测一下,您的两个输入与您向我们展示的样本有所不同,影响关键比较$new-case/@name = $old-case/@name and $new-case/../@name = $old-case/../@name
- 在新集合或旧集合或两者中,......的组合@name和./@name不是唯一的。
要查找数据中的重复项,我会运行如下查询:
let $new-run := collection('collection1'),
$old-run := collection('collection2')
for $name in distinct-values(
for $tc in ($new-run | $old-run)//test-case/@name
return concat($tc/../@name,' || ',$tc/@name)
)
let $old := $old-run//test-case
[concat(../@name,' || ', @name) = $name],
$new := $new-run//test-case
[concat(../@name,' || ', @name) = $name]
where count($old) gt 1
or count($new) gt 1
return <duplicate-id name="{$name}"
old-count="{count($old)}"
new-count="{count($new)}"/>