如何在XQuery中找到两个节点的最低共同祖先?

时间:2015-06-13 06:52:28

标签: xquery basex

假设输入XML是

<root>
<entry>
    <title>Test</title>
    <author>Me</author>
  </entry>
</root>

我想找到titleauthor的最低共同祖先。 我在BaseX中尝试了以下代码:

 let $p := doc('t.xq')//title, 
 $q := doc('t.xq')//author, 
 $cla := ($p/ancestor-or-self::node() intersect $q/ancestor-or-self::node()) 
 return 
    $cla

但它什么都不返回(空白输出)。

3 个答案:

答案 0 :(得分:2)

这是一种可能的方式:

title

简要说明:

  • author:第一个谓词会考虑具有[not(.//*[.//title and .//author])]<entry> <title>Test</title> <author>Me</author> </entry> 后代的元素。

  • {{1}}:然后第二个谓词将相反的条件应用于后代元素,这意味着我们总体上只接受与第一个谓词条件匹配的最内层元素。

输出

{{1}}

答案 1 :(得分:2)

除了返回所有共同祖先之外,您的代码对我来说完全没问题。

最后的共同祖先

由于它们按文档顺序返回,并且最后一个共同祖先也必须是最后一个节点,因此只需使用[last()]谓词进行扩展。

declare context item := document {
  <root>
    <entry>
      <title>Test</title>
      <author>Me</author>
    </entry>
  </root>
};

let $p := //title, 
    $q := //author, 
    $cla := ($p/ancestor-or-self::node() intersect $q/ancestor-or-self::node())[last()]
return 
    $cla

文件和数据库

如果您发布的查询未返回任何内容,则可能正在处理文件t.xqintersect要求在同一个数据库中比较所有节点,每次在文件上调用doc(...)都会创建一个新的内存数据库。在BaseX中使用内容创建数据库,或执行类似

的操作
declare variable $doc := doc('t.xq');

并替换doc(...)之后的$doc次调用(现在引用为该文件创建的单个内存数据库)。

答案 2 :(得分:1)

我使用变量doc('t.xq')在变量$p$q前面更改了$db,如下所示。现在它起作用了(另外,我使用last()来拥有最后一个(最低的)共同祖先)。

let 
$db := doc('t.xq'),
$p := $db//title, 
$q := $db//author, 
$cla := ($p/ancestor-or-self::node() intersect $q/ancestor-or-self::node())[last()] 
return $cla