要求:
将cts/search
查询与XPath查询相结合。
XPath是未知的用户输入字符串。
search:resolve
函数采用“ A cts:query对象,序列化的cts:query或结构化查询(search:query)”。 (Source)
问题:
是否有将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)
如果当前无法将XPath字符串转换为兼容search
的格式,是否还有其他方法可以将XPath和cts / search查询结合使用?
任何帮助将不胜感激!
更新1 :
我尝试使用建议的searchable-expression
选项,但遇到与extract-document-data
结合使用的另一个问题:
import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
search:resolve(
cts:element-value-query(xs:QName("name"), "Mike"),
<options xmlns="http://marklogic.com/appservices/search">
<searchable-expression>/test[age = 20]</searchable-expression>
<extract-document-data>
<extract-path>/test/name</extract-path>
</extract-document-data>
</options>
)
此查询确实返回以下提取的数据:
<search:extracted-none>
</search:extracted-none>
虽然没有可搜索的表达式,但我得到了预期的结果:
<search:extracted kind="element">
<name>Mike</name>
</search:extracted>
如果我没记错的话,searchable-expression的行为与cts:search
的第一个参数相同。阅读文档说:
例如,如果指定// p,则匹配搜索的p个元素 条件返回。
因此,结果节点仅限于searchable-expression,而低于该节点的所有节点都不是我想要的。
答案 0 :(得分:2)
您可以将该XPath传递到<search:options>
中的<searchable-expression>
元素中,它实际上将与您的cts:query
进行“与”运算。在幕后,所有XPath表达式都将转换为优化的查询计划,就像cts:queries
一样(除了XPath表达式将始终被过滤以防止误报,而cts
表达式是可选的) 。
但是我应该注意,评估用户XPath是极其危险的,并且未经检查是对注入攻击的巨大漏洞。您应该验证或清理查询以防止此情况和/或确保查询无法运行更新,即:/x/y/z[xdmp:directory-delete('/')]
。这样的查询顶部就是一个不错的开始:declare option xdmp:update "false";