我有一个类似于以下内容的 XML 文档:
<tt>
<a text="1"/>
<a text="2"/>
...
<a text="n"/>
<b text="14">data</b>
<b text="2">data</b>
...
</tt>
如何选择所有 <b>具有 text 的元素属性不等于 text任何 <a> 的属性元素?我正在使用 XPath 1.0。
我在考虑类似 tt/b[not (tt/a[@text = xxx::@text])] 的事情, 其中xxx应引用tt/b正在检查的元素。我不知 Prop 体怎么做。
最佳答案
/tt/b[@text != ../a/@text] 之类的答案是错误的,并且选择了错误的节点集::
<b text="14">data</b>
<b text="2">data</b>
正如我们所见,第二个选定节点的 text 属性是 2 并且是一个 a 元素,其text 属性为 2。
这是一个正确的 XPath 表达式:
/tt/b[not(@text = ../a/@text)]
根据提供的 XML 文档进行评估时:
<tt>
<a text="1"/>
<a text="2"/>
...
<a text="n"/>
<b text="14">data</b>
<b text="2">data</b>
...
</tt>
它只正确选择了一个节点:
<b text="14">data</b>
解释:
根据定义 the XPath != operator 有一个非常不直观的行为,只要它的至少一个参数是一个节点集:
来自W3C XPath 1.0 Recommendation :
"If one object to be compared is a node-set and the other is a number, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the number to be compared and on the result of converting the string-value of that node to a number using the number function is true. If one object to be compared is a node-set and the other is a string, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the string-value of the node and the other string is true"
在元素的这种特殊情况下:
<b text="2">data</b>
比较:
@text != ../a/@text
是 true() 即使存在:
<a text="2"/>
因为至少存在一个 ../a 元素(实际上不止一个),所以其 text 属性的字符串(或数字)值不是等于 "2"。
这是一个众所周知的事实和常见问题解答:除非您完全知道自己在做什么,否则请始终避免使用 != 运算符!
这个问题的正确解决方案是像这样使用not()函数:
not(@text = ../a/@text)
仅当 @text = ../a/@text 为 false() 时,此表达式才计算为 true() -- 即仅当甚至没有一个 ../a/@text 的字符串值等于上下文节点的 text 属性的字符串值时。
基于 XSLT 的验证:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select="/tt/b[not(@text = ../a/@text)]"/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的 XML 文档(如上)时,会生成正确的结果:
<b text="14">data</b>
关于xml - XPath/XSLT : how to select all elements that satisfy a condition involving another set of elements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7406444/