想象一下,如果我有一个 xml 文档以以下格式存储在 Marklogic 中:

<document>
   <id>DocumentID</id>
   <questions>
       <question_item>
            <question>question1</question>
            <answer>answer1</answer>
       </question_item>
       <question_item>
            <important>high</important>
            <question>question2</question>
            <answer>answer2</answer2>
       <question_item>
</document>

基本上,每个文档都有许多问题,只有其中一些有一个元素。我想以平面格式返回所有“重要”问题,并使用从其提取的文档(例如,id)中获取的元数据。

以下 xquery 似乎有效,而且速度相当快:
for $x in cts:search(/document,
  cts:element-query(xs:QName("important"),cts:and-query((
))
), "unfiltered" , 0.0)
return for $y in $x/questions/question_item

  return
    if ($y/important) then
    fn:concat($x/id,'|',
        $y/question,'|',
        $y/answer,
        $y/important
    )
    else ()

这似乎有效并且相当快。但是,我通常发现 for 循环并不是在 xquery 中工作的最快方式。该解决方案似乎确实是一种相对麻烦的方法。有没有更好的方法来最初只返回“重要”节点,但仍然可以访问主要文档元素?

最佳答案

就我个人而言,我发现条件逻辑比 for 循环更麻烦,但我认为您可以为更简单的查询删除其中的一个。您可以简单地将它们分配给一个变量,这将允许您引用它们,而不是循环遍历第一个文档序列。然后在您的循环中,使用谓词将 question_item 限制为具有 important 元素的那些,从而消除对条件的需要:

let $documents := cts:search(/document,
  cts:element-query(xs:QName("important"), cts:and-query(())
  ), "unfiltered" , 0.0)
for $y in $documents/questions/question_item[important]
return fn:concat($x/id,'|',
  $y/question,'|',
  $y/answer,
  $y/important)

关于xquery - Marklogic xquery 并有效地循环遍历子元素,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41371117/

10-13 02:19