Marklogic 结合XPath和搜索查询

Marklogic 结合XPath和搜索查询,marklogic,Marklogic,要求: 将cts/search查询与XPath查询相结合。 XPath是未知的用户输入字符串 search:resolve函数接受“一个cts:query对象、一个序列化的cts:query或一个结构化查询(search:query)。”() 问题: 是否有将XPath转换为cts或结构化查询的api,以便我可以将XPath和其他搜索查询组合在一起 不起作用示例: xquery version "1.0-ml"; let $doc := <test> <name&

要求:

cts/search
查询与XPath查询相结合。 XPath是未知的用户输入字符串

search:resolve
函数接受“一个cts:query对象、一个序列化的cts:query或一个结构化查询(search:query)。”()

问题:

是否有将XPath转换为cts或结构化查询的api,以便我可以将XPath和其他搜索查询组合在一起

不起作用示例:

xquery version "1.0-ml";
let $doc := 
  <test>
    <name>Mike</name>
    <age>20</age>
  </test>
return xdmp:document-insert('mike.xml', $doc);

import module namespace search = "http://marklogic.com/appservices/search"
    at "/MarkLogic/appservices/search/search.xqy";

let $xpath := '/test[name="Mike"]'
let $cts-query := cts:and-query(
   xpathToCts($xpath), (: Somehow convert XPath to cts query here :)
   cts:element-value-query(xs:QName("age"), "20")
)

return search:resolve($cts-query)
此查询确实返回以下提取的数据:

<search:extracted-none>
</search:extracted-none>

在没有可搜索表达式的情况下,我得到了预期的结果:

<search:extracted kind="element">
   <name>Mike</name>
</search:extracted>

迈克
如果我没有弄错的话,可搜索表达式的行为与
cts:search
的第一个参数相同。阅读文件,上面写着:

例如,如果指定//p,则指定与搜索匹配的p个元素 返回条件


因此,生成的节点仅限于可搜索表达式和下面的所有节点,这不是我想要的

您可以将该XPath传递到
中的元素中,它将基本上与您的
cts:query
一起进行编译。在后台,所有XPath表达式都被转换为优化的查询计划,就像
cts:querys
(XPath表达式总是被过滤以防止返回误报,而过滤是可选的
cts
表达式)


但我应该注意到,评估用户XPath是极其危险的,而未经检查,这对于注入攻击来说是一个巨大的漏洞。您应该验证或清理查询以防止出现这种情况和/或确保查询无法运行更新,即:
/x/y/z[xdmp:directory delete('/')]
。查询顶部的类似内容是一个良好的开端:
declare option xdmp:update“false”

+1。最好的方法是避免使用XPath进行查询,原因如下:XPath的表达能力太强,无法保证转换为基于索引的高效、未过滤的查询,而且XPath很难净化以确保安全性。如果必须支持层次查询,最好使用层次的JSON或XML表示,并将其转换为组合的cts.jsonPropertyScope()或cts.elementQuery()查询。我添加了一个更新,其中引用了您的答案。遗憾的是,我不能使用searchable表达式,因为它将结果节点更改为searchable表达式中给出的节点。因此,我正在进一步寻找将XPath查询转换为cts/search兼容格式的方法。谢谢你的回答@瓦格纳:是的,表达式选择XPath中表示的节点,但您可以修改其他XPath以适应更改,即
/name
-或者如果路径可以选择不同级别的节点,
/祖先或self::test/name
。一个内务说明-通常,将问题的内容更改这么多会更好地作为一个新问题。Q&A之间的所有更改和沟通都会让未来的用户感到困惑,因此用户必须遵循。@wst您是对的,我可以调整提取路径,但我可以看到其他限制。想象一个可搜索的表达式,如
/test/details[age=20]
(我将age移到元素details中)。现在,名称的
元素值查询
不再有效,因为上下文位于
详细信息
中。另一方面,可搜索表达式
/test[details/age=20]
仍然有效。因此,这意味着我将不得不期望我的用户“不要切换搜索上下文”,这将是可行的最后手段,但有点扫兴。希望这种说法有道理。@WagnerMichael我想你没有读到我的全部评论。更改搜索上下文可以通过在提取表达式中使用
祖先或self::
XPath轴来处理(也可以重写该约束以不更改上下文,即
/test[details/age=20]
)。如果您强制搜索API在文档/片段级别使用
未筛选的
进行查询,则此操作有效。
<search:extracted kind="element">
   <name>Mike</name>
</search:extracted>