XQuery祖先轴不';不起作用,但显式XPath起作用
考虑以下XQuery祖先轴不';不起作用,但显式XPath起作用,xpath,xquery,marklogic,axes,Xpath,Xquery,Marklogic,Axes,考虑以下XML片段: <doc> <chapter id="1"> <item> <para>some text here</para> </item> </chapter> </doc> 在那个例子中,$chapter总是空出来。但是,如果我编写与以下类似的函数(即,不使用祖先轴),我将得到所需的“chapter”元素: 问题
XML
片段:
<doc>
<chapter id="1">
<item>
<para>some text here</para>
</item>
</chapter>
</doc>
在那个例子中,$chapter总是空出来。但是,如果我编写与以下类似的函数(即,不使用祖先轴),我将得到所需的“chapter”元素:
问题是,我不能像后一个示例中那样使用显式路径,因为我要搜索的XMl
不能保证每次都将“chapter”元素作为祖父母。它可能是曾祖父母或曾祖父母,依此类推,如下所示:
<doc>
<chapter id="1">
<item>
<subItem>
<para>some text here</para>
</subItem>
</item>
</chapter>
</doc>
这里有一些文字
有人解释为什么axis不工作,而显式XPath工作吗?还有,有人对如何解决这个问题有什么建议吗
多谢各位
解决方案: 这个谜现在已经解开了 所讨论的节点是在另一个函数中重新创建的,其结果是剥离了它的所有祖先信息。不幸的是,以前的开发人员没有记录这个奇妙的小功能,并且花费了我们很多时间 因此,祖先轴完全按照它应该的方式工作-它只是被应用到一个欺骗节点
我感谢你们所有人为回答我的问题所做的努力。这似乎让我感到惊讶;您使用的是哪种XQuery实现?对于BaseX,以下查询
declare function local:doSomething($para) {
let $chapter := $para/ancestor::chapter
return $chapter
};
let $xml :=
<doc>
<chapter id="1">
<item>
<para>some text here</para>
</item>
</chapter>
</doc>
return local:doSomething($xml//para)
declare函数local:doSomething($para){
让$chapter:=$para/祖先::chapter
返回$chapter
};
让$xml:=
这里有一些文字
返回本地:doSomething($xml//para)
…返回
<chapter id="1">
<item>
<para>some text here</para>
</item>
</chapter>
这里有一些文字
祖先轴工作正常。我怀疑你的问题是名称空间。您展示的示例和我运行的示例(如下)包含没有任何名称空间的XML。如果您的XML有一个名称空间,那么您需要在祖先XPath中提供该名称空间,如下所示:$para/祖先:foo:chapter
,在这种情况下,前缀\u foo\uu绑定到chapter元素的正确名称空间
let $doc := <doc>
<chapter id="1">
<item>
<para>some text here</para>
</item>
</chapter>
</doc>
let $para := $doc//para
return $para/ancestor::chapter
let$doc:=
这里有一些文字
设$para:=$doc//para
返回$para/祖先::章
结果:
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="1">
<item>
<para>some text here</para>
</item>
</chapter>
这里有一些文字
我也怀疑名称空间。如果$para/../..
有效,但$para/parent::item/parent::chapter
结果为空,则您知道这是名称空间的问题
请在内容顶部查找xmlns声明,例如:
<doc xmlns="http://example.com">
...
</doc>
你用什么前缀并不重要。重要的是名称空间URI(http://example.com
在上述示例中)匹配
。/..
选择所需的元素是有意义的,因为。
是parent::node()
的缩写,它选择父节点而不考虑其名称(或命名空间)。而祖先::chapter
将只选择不在名称空间中的
元素(除非您声明了默认元素名称空间,这在XQuery中通常不是一个好主意,因为它会影响您的输入和输出)。这些事情几乎总是归结为名称空间!作为一个100%确认名称空间不是问题的诊断者,您可以尝试:
declare function local:doSomething($para) {
let $chapter := $para/ancestor::*[local-name() = 'chapter']
return $chapter
};
谢谢你,克里斯蒂安。我正在使用MarkLogic 4.2提供的任何XQuery实现。是的,我同意使用运行在MarkLogic 5上的查询计算器可以很好地工作。你使用的是什么版本的4.2?我听说上面的代码在4.2-4中运行得很好,所以一些环境问题可能会让你感到困惑。谢谢你,克拉克。我已经通过MarkLogic 4.2中的错误日志验证了$para是我所期望的。我知道这应该行得通,但不知为什么不行。这里正在进行大量的扫墓活动。:^)我怀疑你的问题是名称空间。您展示的示例和我运行的示例包含没有任何名称空间的XML。如果XML确实有名称空间,则需要在祖先XPath中提供名称空间,如:$para/祖先:foo:chapter,在本例中,前缀foo绑定到chapter元素的正确名称空间。@mahdaeng,您可能已经在模块顶部为某些特定名称空间声明了默认元素名称空间,而您的XML没有或没有其他名称空间。先生们,感谢您在这里提到名称空间可能会导致问题。但是,在本文档中没有使用名称空间。
<doc xmlns="http://example.com">
...
</doc>
declare namespace my="http://example.com";
declare function doSomething($para){
let $chapter := $para/ancestor::my:chapter
return "some stuff"
};
declare function local:doSomething($para) {
let $chapter := $para/ancestor::*[local-name() = 'chapter']
return $chapter
};