我有一个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
总是一个字符串,这样的事情是微不足道的。
感谢。
答案 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
结果。