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>