如何使用 XPath 检查节点值是否为数字?
有任何想法吗?
针对 NaN 测试该值:
<xsl:if test="string(number(myNode)) != 'NaN'">
<!-- myNode is a number -->
</xsl:if>
这是一个较短的版本(感谢 @Alejandro):
<xsl:if test="number(myNode) = myNode">
<!-- myNode is a number -->
</xsl:if>
测试变量 $v
中包含的值是否可以用作数字的最短方法是:
number($v) = number($v)
您只需要将上面的 $v
替换为您要测试其值的表达式。
解释:
如果 $v
是数字或表示数字的字符串,number($v) = number($v)
显然是正确的。
对于布尔值也是如此,因为 number(true())
是 1 而 number(false)
是 0。
每当 $v
不能用作数字时,则 number($v)
为 NaN
并且 NaN 不等于任何其他值,甚至不等于它自己。
因此,上述表达式仅对值可以用作数字的 $v
为真,否则为假。
number($v) = number($v)
与 number($v) = $v
产生不同结果的情况吗?
number($v) = number($v)
产生与 number($v) = $v
不同的结果的情况吗?毫无疑问,这可以从您所写的内容中得出,但我没有看到您在哪里明确解决了这个问题。对不起,如果我很密集。 IOW,您的解决方案和@Oded 的/@Alejandro 的解决方案是否总是产生相同的结果?
XPath 2.0 中有一个很棒的类型测试运算符,您可以使用:
<xsl:if test="$number castable as xs:double">
<!-- implementation -->
</xsl:if>
我不是试图提供另一种替代解决方案,而是对这个问题的“元视图”。
Oded 和 Dimitre Novatchev 已经提供的答案是正确的,但人们对“价值是一个数字”这句话的真正含义是,我该怎么说,可以解释。
在某种程度上,这一切都涉及到这个听起来很奇怪的问题:“你想如何表达你的数值?”
XPath 函数 number()
处理具有
可能的前导或尾随空格
仅在负值上的前符号字符
点作为小数分隔符(整数可选)
[0-9] 范围内的所有其他字符
请注意,这不包括数值表达式
以指数形式表示(例如 12.3E45)
可能包含正值的符号字符
有正负零之分
包括正无穷或负无穷的值
这些不仅仅是构成的标准。具有根据架构有效 xs:float
值的内容的元素可能包含上述任何特征。然而 number()
将返回值 NaN
。
因此,回答您的问题“如果节点值是数字,我如何使用 XPath 检查?”是“使用已经提到的使用 number()
的解决方案”或“使用单个 XPath 1.0 表达式,你不能”。想想你可能遇到的可能的数字格式,如果需要,写一些逻辑来进行验证/数字解析。例如,在 XSLT 处理中,这可以通过几个合适的额外模板来完成。
PS。如果你只关心非零数字,最短的测试是
<xsl:if test="number(myNode)">
<!-- myNode is a non-zero number -->
</xsl:if>
我发现非常有用的是以下内容:
<xsl:choose>
<xsl:when test="not(number(myNode))">
<!-- myNode is a not a number or empty(NaN) or zero -->
</xsl:when>
<xsl:otherwise>
<!-- myNode is a number (!= zero) -->
</xsl:otherwise>
</xsl:choose>
我一直在处理 01 - 这是一个数字。
string(number($v)) != string($v)
进行隔离
NaN
中,数字数据类型的值不等于任何数字值,并且为了比较,如果至少一个参数是数字数据类型,那么另一个参数被强制转换为数字,这是最短数字测试:number(MyNode)=MyNode
Required item type of first operand of '=' is numeric; supplied value has item type xs:string;
) 上的类型不匹配,@Alejandro 的简短版本在 XPath 2.0 中完全失败,但 Dimitre 的解决方案工作正常。