XQuery 祖先轴不起作用,但显式 XPath 起作用

mah*_*eng 0 xpath xquery axes marklogic

考虑以下XML片段:

<doc>
    <chapter id="1">
        <item>
            <para>some text here</para>
        </item>
    </chapter>
</doc>
Run Code Online (Sandbox Code Playgroud)

在 中XQuery,我有一个函数需要根据作为参数传入的给定“para”元素的祖先章节执行一些操作,如下面的精简示例所示:

declare function doSomething($para){
    let $chapter := $para/ancestor::chapter
    return "some stuff"
};
Run Code Online (Sandbox Code Playgroud)

在该示例中,$chapter始终显示为空。但是,如果我编写类似于以下的函数(即不使用祖先 axis),我会得到所需的“章节”元素:

declare function doSomething($para){
    let $chapter := $para/../..
    return "some stuff"
};
Run Code Online (Sandbox Code Playgroud)

问题是我不能像后一个示例中那样使用显式路径,因为XMl我将要搜索的内容不能保证每次都将“chapter”元素作为祖父母。它可能是曾祖父母曾曾祖父母,等等,如下所示:

<doc>
    <chapter id="1">
        <item>
            <subItem>
                <para>some text here</para>
            </subItem>
        </item>
    </chapter>
</doc>
Run Code Online (Sandbox Code Playgroud)

有谁能解释为什么轴不起作用,而显式 XPath 却起作用?另外,有人对如何解决这个问题有什么建议吗?

谢谢。


解决方案:

现在这个谜团已经解开了。

有问题的节点是在另一个函数中重新创建的,其结果是剥离了它的所有祖先信息。不幸的是,以前的开发人员没有记录这个奇妙的小功能,并且花费了我们很多时间。

因此,祖先轴完全按照其应有的方式工作 - 它只是应用于欺骗性节点。

我感谢大家为回答我的问题所做的努力。

Cla*_*hey 5

祖先轴确实工作得很好。我怀疑你的问题是命名空间。您展示的和我运行的示例(如下)具有没有任何名称空间的 XML。如果您的 XML 有命名空间,那么您需要在祖先XPath中提供该命名空间,如下所示:$para/ancestor:foo:chapter在本例中,prefix _foo_ is绑定到章节元素的正确命名空间。

let $doc := <doc>
    <chapter id="1">
        <item>
            <para>some text here</para>
        </item>
    </chapter>
</doc>

let $para := $doc//para
return $para/ancestor::chapter
Run Code Online (Sandbox Code Playgroud)

结果:

<?xml version="1.0" encoding="UTF-8"?>
<chapter id="1">
  <item>
    <para>some text here</para>
  </item>
</chapter>
Run Code Online (Sandbox Code Playgroud)