结合XPath和搜索查询

时间:2019-06-03 11:57:25

标签: marklogic

要求:

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,而低于该节点的所有节点都不是我想要的。

1 个答案:

答案 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";