如何引用XPath点运算符的原点值?

时间:2018-01-14 13:26:57

标签: xml xpath

这是我的文件:

<library>
  <reserved>
    <book>Don Quixot</book>
  </reserved>
  <all>
    <book>Don Quixot</book>
    <book>War and Peace</book>
  </all>
</library>

我试图选择现在没有预订的所有书籍:

/library/all/book[not(/library/reserved/book[.=current()])]

这不起作用,因为第二对方括号内的current()已经在reserved元素的范围内。我应该使用什么而不是current()

1 个答案:

答案 0 :(得分:3)

  

我正在尝试选择现在没有预订的所有书籍:

<强>答案:

/library/all/book[not(text() = /library/reserved/book/text())]

我之前的回答并不适用于所有情况(请参阅@ MichaelKay的评论)。

我的删除答案不起作用的原因是因为谓词试图在reserved/book/text()选择的节点集中找到至少一个节点,其中的文本不等于当前文字()。这不同于找到一本书,其中存在具有相同文本的保留书。

我的新答案中的谓词将尝试查找具有相同文本的保留书籍,如果没有这样做(是否没有保留书籍或没有保留书籍具有相同的文本,not()将否定false结果并返回未保留的书。

有关进一步说明,请参阅this对其他问题的回答。

来自spec

  

如果要比较的一个对象是节点集而另一个是字符串,那么当且仅当节点集中有一个节点使得执行比较的结果时,比较才为真。节点的字符串值和另一个字符串为真。

!=运算符如果找到至少一个具有不同文本的节点,则会尝试返回true。如果至少一个节点具有相同的文本,=运算符将尝试返回true。如果节点集为空,则两者都将返回false。因此,如果没有保留的书籍(空节点集),或者如果没有任何保留的书籍具有相同的文本,则解决方案是返回true,ergo not(text() = /library/reserved/book/text())

如果保证每个列表中没有两个<book>元素具有相同的文本内容,那么这将起作用:

/library/all/book[text() != ../../reserved/book/text()]