【发布时间】:2025-12-05 21:55:02
【问题描述】:
自从我们更新库以来,我已经面临这个问题 2 天了。我们有很多这样的 xpath:
/root/temp[@attr!='abcd']
自从我们将库更新到 2.13 后,这些不再起作用。这些在 2.11 版本中运行良好,但它们不再适用于 >=2.12 版本。这个问题很容易重现:
String test = "<root><attr temp='abcde'></attr></root>";
VTDGen vg = new VTDGen();
vg.setDoc(test.getBytes());
vg.parse(false);
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/root/attr[@temp!='abcd']");
System.out.println(ap.evalXPath());//expecting a positive int, get -1 instead
由于另一个错误,我们已经更新,但现在我们真的被这个问题困住了。有任何想法吗?我们可以使用另一种语法来绕过此错误吗?我们尝试使用 /root/attr[not(@temp='abcd')] 并且它正在处理这个简单的案例,但我们不确定这对于涉及“!=”作为运算符的每个 xpath 是否有效。
请注意,2.11 甚至可以使用像 /root/attr[@temp!=''] 这样的 xpath,在该版本之后,!= 运算符似乎已损坏,至少对于我们习惯的使用而言。
编辑: 我们不使用“not”语法的原因是因为在这种情况下
<root>
<nodes>
<node attr="1" />
<node attr="2" />
<node attr="3" />
</nodes>
<nodi>
<nodo attr="1" />
<nodo attr="2" />
<nodo attr="3" />
</nodi>
</root>
这些 xpath:
/root/nodes/node[@attr!=/root/nodi/nodo/@attr]
/root/nodes/node[not(@attr=/root/nodi/nodo/@attr)]
返回不同的结果。我知道这是一个非常微不足道的例子,只是我们不能通过简单的查找和替换来确保所有工作都按预期工作。我刚刚深入研究了源代码,我注意到解析器只是将 !超出 xpath 表达式。
【问题讨论】:
-
交叉检查:你能试试这个替代 XPath
/root/temp[not(@attr = 'abcd')]吗?另外,请确认您的 XML 不包含任何命名空间。 -
@Tomalak 我们确实做到了并且它有效(我一开始忘记在我的帖子中添加@,已修复),但是......我用一个例子编辑了我的帖子,说明了为什么我们想要避免盲目地改变所有的xpaths
-
“在 XPath 中 [a != b] 是否总是等价于 [not(a = b)]?” 顺便提一下,这是一个很好的问题。简短,准确回答,到目前为止,我认为以前没有人问过。
-
好的,我会调查的...我记得有人提出了这个问题,并在 2.13 中已经修复...会再看一遍