1

我有两个元素列表,用于查询第三种类型的元素(在 eXist DB 中)。但是由于我只想要两个查询都找到的结果(即满足两组初始参数),所以我对这两个子结果进行了交集:

let $aList1 := for $elementB in $elementListB return //ElementA[ft:query(@referenceB, $elementB/@id)]
let $aList2 := for $elementC in $elementListC return //ElementA[ft:query(@referenceC, $elementC/@id)]
let $results := $aList1 intersect $aList2

问题是,我需要在起始列表中的每个元素上调用一个函数来获取一些额外的信息。通常我会做这样的事情:

let $aList1 := for $elementB in $elementListB
    let $additionalInfo := additionalInfoFunction($elementB)
    return
        <wrapper>
        <additionalInfo>{$additionalInfo}</additionalInfo>
        {
             //ElementA[ft:query(@referenceB, $elementB/@id)]
        }
        </wrapper>

但是,如果我这样做,我将无法执行交集,$aList1因为$aList2交集与引用而不是值一起使用。

我想像这样调用additionalInfoFunction路口之后:

return for $result in $results
let $elementB := $elementListB[@id = $result/@referenceB]
let $additionalInfo := additionalInfoFunction($elementB)
return
    <wrapper>
    <additionalInfo>{$additionalInfo}</additionalInfo>
    {
         BLA BLA
    }
    </wrapper>

但这里的问题是,虽然$elementListB$elementListC包含几个元素,$results但可以包含数百个元素,这是一个问题,因为additionalInfoFunction它相对昂贵。

这里有一些我看不到的聪明的解决方法吗?

4

1 回答 1

0

XQuery 是一种具有不可变变量的函数式语言,因此没有副作用。

但是,如果我这样做,我将无法执行交集, $aList1因为$aList2交集与引用而不是值一起使用。

函数或运算符是否intersects会返回引用仅与实现相关(引用可能更快),但由于所有值都是不可变的,这对您来说永远不会成为问题。


实际问题是相关的,但不相似;intersects不做深度相等,而只查看一些内部“节点ID”(如果需要,也可以参考)。创建两个元素 - 尽管包含相同的内容 - 将创建不同的节点,因此intersect不会返回任何结果。

您将不得不建立自己的交叉点,这并不难:

let $a := (<a><a1/><a2/></a>, <b><b1/><b2/></b>),
    $b := (<a><a1/><a2/></a>, <c><c1/><c2/></c>)

return $a[
  some $e in $b
  satisfies deep-equal(., $e)
]

这将返回所有元素$a,其中有一些元素$b深度等于 from $a

于 2013-01-13T20:28:22.670 回答