在XQuery中,如何从字符串中评估xpath?

时间:2014-08-22 20:34:35

标签: xquery marklogic

我有一个XQuery脚本,我想在将新文档导入数据库时​​进行评估。我想从字符串中使用谓词计算Xpath表达式,并使用结果选择适当的集合。

如果所有代码都在XQuery文件中,那么它可以正常工作。我想让它更具活力,并阅读XPath 表达式 - >动态集合映射。然后,在每个文档中,当XPath表达式返回一个节点时,我找到了正确的集合。

这可能吗? xdmp:unpath()功能不足。它不支持谓词。 xdmp:eval()xdmp:value()似乎有效,但我无法让它们只针对单个文档。要么是这样,要么就是在500个左右的文档之后它们才开始失败(对任何XPath表达式都返回true)。

我希望能够做到这样的事情:

(: Get XML from MarkLogic Record Loader. :)
let $doc := xdmp:unquote($XML-STRING, $UNQ-NAMESPACE, $UNQ-OPTIONS)

(: Get XPath expression from database. :)
let $xpath := doc("/mappings.xml")/mappings/rule/xpath

(: Evaluate. :)
let $result := some-function($doc, $xpath) 

(: Use the result.
return
    if(fn:count($result) > 0)
        ( $collection )
    else
        ()   

是否有一些构造会使“some-function($ doc,$ xpath)”工作?

似乎在XQuery中,XPath表达式是语法的一部分,不能用字符串替换。我已经习惯了像Perl这样的其他语言,其中XPath总是一个字符串,这样的事情是微不足道的。

感谢。

3 个答案:

答案 0 :(得分:1)

正确的工具是xdmp:value。但是,您可能在语法方面遇到了一些麻烦。我用这个:

xdmp:value(concat('$doc', $xpath))

构造一个相对于$ doc的表达式,类似于$doc/a/b/c。然后我们可以在当前上下文中评估该表达式,其中$doc已经定义。

let $doc := xdmp:unquote('<x>some xml <i>from somewhere</i></x>')
let $xpath := '/x/i'
return xdmp:value(concat('$doc', $xpath))
=>

<i>from somewhere</i>

请注意xdmp:unquote生成文档节点,因此第一步是x根元素。

您可以将此封装在自己的函数中,然后您将some-function($doc, $xpath)工作。

declare function local:my-unpath($doc as node(), $xpath as xs:string)
as item()*
{
  xdmp:value(concat('$doc', $xpath))
};

let $doc := xdmp:unquote('<x>some xml <i>from somewhere</i></x>')
let $xpath := '/x/i[starts-with(., "from")]'
return local:my-unpath($doc, $xpath)

答案 1 :(得分:0)

听起来你正在寻找xdmp:unpath()

答案 2 :(得分:0)

您还可以将XML配置文件重写为XSLT,然后使用xdmp:xslt-invoke对其进行评估。它仍然是XML,只是格式有点不同。每个规则都是模板match,返回带有集合名称的xsl:text结果。