1

我正在使用 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>
};

在我看来,它对 $new-case 和 $old-case 之间的每个组合进行了排列,但我不知道为什么。我会尝试过滤掉重复项,但它们不是完全相同的重复项,有时似乎使用 $old-case 代替 $new-case。

4

2 回答 2

1

在我看来,它对 $new-case 和 $old-case 之间的每个组合进行了排列

这正是正在发生的事情,由于您的for. 例如:

for $x in (1, 2, 3), $y in ('a', 'b', 'c')
return <z>{$x, $y}</z>

=>

<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
...
于 2013-09-11T21:31:30.173 回答
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)}"/>
于 2013-09-16T14:44:08.777 回答