我正在阅读和测试 XQuery,并且喜欢使用 BaseX(www.basex.org) 和 saxon-HE 9.4.0.6N 的测试工具。 对于以下简单 XML 文件 - 没有附加任何模式到 example.xml:
<rootab>
<l1>
<items p="a">
<itema x1="10" id="abc">testa</itema>
<itemb x1="10" id="dfe">testb</itemb>
<itemc x1="10" id="jgh">testc</itemc>
</items>
</l1>
<l2>
<items p="b">
<itema x1="10" xidref="abc">testa</itema>
<itemc x1="10" xidref="jgh">testc</itemc>
<itemd x1="10" xidref="abc">testA101</itemd>
<iteme x1="10" xidref="jgh">testB202</iteme>
</items>
</l2>
</rootab>
在 Basex_GUI 中,如果我输入以下 XPath 表达式://idref("abc")/..
结果是:<itema x1="10" xidref="abc">testa</itema>
在 BaseX_GUI 中,如果我添加简单的 XQuery 表达式:
for $x in doc('sample.xml')//idref("abc")/..
return <aaa>{$x}</aaa>
结果是:
<aaa>
<itema x1="10" xidref="abc">testa</itema>
</aaa>
<aaa>
<itemd x1="10" xidref="abc">testA101</itemd>
</aaa>
q1) 为什么 XPath 表达式只返回一个节点?我预计有两个...
在 Saxon 中,使用以下 xql 文件:
<test>
{
doc('sample.xml')//idref("abc")/..
}
</test>
或 XQuery 表达式,我通过运行命令 query sample.xql
收到相同的结果:
<?xml version="1.0" encoding="UTF-8"?><test/>
q2)我的 Saxon 测试出了什么问题?
提前感谢您的帮助!
最佳答案
基本上,idref()
对 DTD 验证很敏感 - 它识别 DTD 中声明为 IDREF 类型的属性。
您还没有向我们展示您的 DTD,更重要的是,您还没有向我们展示如何提供查询的输入。有很多构建输入的方法,其中属性的“IDREF-ness”会丢失 - 例如,通过 DOM。即使您在 Saxon 中使用 doc() 函数,输入树的构建方式也取决于许多因素,包括配置选项和 URIResolver。
我发现您正在使用 .NET。当 Saxon 在 .NET 上使用 Microsoft XML 解析器时,它不知道哪些属性是 ID 和 IDREF,因此 id()
和 idref()
函数不知道工作(MS 解析器根本不提供此信息)。因此,您需要使用 Saxon 产品附带的 JAXP 解析器 (Xerces)。我认为这是现在的默认设置。
所以这并不是一个真正的答案,但希望有一些背景知识可以解释一些可能出错的事情。
关于使用 idref 的 XPath 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13715784/