如何向需要感兴趣的列表中的节点添加其他元素

时间:2013-01-13 16:21:55

标签: xquery exist-db

我有两个元素列表,用于查询第三类元素(在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相对较贵。< / p>

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

1 个答案:

答案 0 :(得分: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的所有元素,$a中有一些元素与[{1}}中的元素深度相等。