我正在尝试为以下xml文件创建一个xpath表达式(显然缩写)。
<estimate>
<heights id="4.1">
<year>1985</year>
</heights>
<heights id="4.2">
<year>1986</year>
</heights>
<heights id="4.3">
<year>1987</year>
</heights>
.
.
.
<heights id="x.x">
<year>XXXX</year>
</heights>
</estimate>
我正在使用的xpath表达式是:
/estimate/heights[@id>4.2]
所以我基本上在寻找具有大于4.2的id的节点。虽然这在我玩它时似乎有效,但我担心我实际上并没有比较浮动到浮动或双重。如果我正确阅读XPATH 2.0的维基百科条目,似乎它会将属性转换为适当的类型:
如果没有使用模式,则节点将是无类型的,并且类型为 得到的原子值将是无类型的原子。键入的原子值是 检查以确保它们具有适合上下文的类型 使用它们的地方:例如,不可能乘以a 按号码约会。相反,无类型的原子价值跟随弱势 键入规则:它们会自动转换为类型 适合于使用它们的操作:例如使用 算术运算将无类型的原子值转换为该类型 双
我已经做了很多搜索,但没有找到任何确定的东西(我不清楚以上引用的陈述是否适用于我的情况。)
答案 0 :(得分:2)
首先,您确实需要明确这是XPath 1.0还是XPath 2.0(或XPath 2.0在向后兼容模式下运行)。对于这个特定的例子,规则可能具有相同的效果,但它们的表达方式非常不同。
在XPath 1.0中,您将节点集与数字(= double)进行比较,如果转换为数字(= double)后节点集中的任何节点大于4.2,则结果为true。如果节点集为空(即如果@id不存在),或者转换产生NaN(即,如果@id不是数字),则结果为false。
在XPath 2.0中,假设数据是无类型的(即,它不是模式感知处理器),则将节点序列与xs:decimal进行比较。节点被雾化,产生一系列xs:untypedAtomic值,并且这些值被转换为xs:double以进行比较(因为另一个操作数是数字)。同样,如果任何值大于4.2,答案都是正确的。与XPath 1.0规则唯一有效的区别是,如果@id不是数字,则转换失败并且您得到动态错误,而XPath 1.0给出“false”。
在启用了向后兼容性的XPath 2.0中,转换为double使用number()函数而不是强制转换,因此非数字@id值将转换为NaN,结果为false,因为它在XPath 1.0中。