这是我的文件:
<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()
?
答案 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()]