伪代码类似于:
let $myNode as node() := $node
for $subpath in tokenize($path,'/')
$myNode := $myNode/*[name()=$subpath] (: Here is the invalid line :)
我知道在xQuery 3.0中有一个运算符,我要求xQuery 1.0。
答案 0 :(得分:3)
没有 XQuery 2.0 ,但是无论版本如何,只有 FLWOR 表达式才能实现您想要做的事情。必须在迭代之间更新当前节点集,而不是 FLWOR 表达式的工作方式。
也就是说,使用 XQuery 1.0 中的递归函数可以轻松实现您想要做的事情:
declare function local:path(
$context as node()*,
$steps as xs:string*
) as node()* {
if(empty($steps)) then $context
else local:path(
$context/*[name() = $steps[1]],
$steps[position() gt 1]
)
};
您可以使用local:path(document{ <x><y>foo</y><z/></x> }, tokenize("x/y", '/'))
调用它。
在 XQuery 3.0 中,如果没有新的顶级功能,它会更容易实现:
fn:fold-left(
function($context, $step) {
$context/*[name() eq $step]
},
document{ <x><y>foo</y><z/></x> },
tokenize('x/y', '/')
)
函数fn:fold-left(..)在内部处理递归,您只需指定如何修改每个步骤中设置的上下文。