【问题标题】:XPath test if node value is number如果节点值为数字,则 XPath 测试
【发布时间】:2011-04-20 17:46:07
【问题描述】:

如何使用 XPath 检查节点值是否为数字?

有什么想法吗?

【问题讨论】:

    标签: xpath


    【解决方案1】:

    我一直在处理 01 - 这是一个数字。

    string(number($v)) != string($v) 进行隔离

    【讨论】:

      【解决方案2】:

      XPath 2.0 中有一个很棒的类型测试运算符,您可以使用:

      <xsl:if test="$number castable as xs:double">
          <!-- implementation -->
      </xsl:if>
      

      【讨论】:

        【解决方案3】:

        我觉得非常有用的是:

        <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>
        

        【讨论】:

          【解决方案4】:

          你总是可以这样使用:

          string(//Sesscode) castable as xs:decimal
          

          castable 由 W3C here 记录。

          【讨论】:

            【解决方案5】:

            我并不是要提供另一种替代解决方案,而是要针对此问题提供“元视图”。

            Oded 和 Dimitre Novatchev 已经提供的答案是正确的,但人们对“价值是一个数字”这句话的真正含义可能是,我该怎么说,可以解释。

            在某种程度上,这一切都涉及到这个听起来很奇怪的问题:“你想如何表达你的数值?”

            XPath 函数number() 处理具有

            • 可能的前导或尾随空格
            • 前面的符号字符仅适用于负值
            • dot 作为小数分隔符(整数可选)
            • 范围 [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>
            

            【讨论】:

            • +1 很好地详细解释了问题背后的问题:OP 可能意味着什么,或者如果他知道要问什么会意味着什么。
            【解决方案6】:

            测试变量$v中包含的值是否可以用作数字的最短方法是

            number($v) = number($v)
            

            您只需将上面的$v 替换为您要测试其值的表达式即可。

            解释

            number($v) = number($v) 显然是真的,如果$v 是一个数字,或者一个代表数字的字符串。

            对于布尔值也是如此,因为 number(true()) 是 1,number(false) 是 0。

            只要$v不能用作数字,那么number($v)就是NaN

            并且 NaN 不等于任何其他值,甚至不等于它自己。

            因此,上述表达式仅对可以用作数字的$v为真,否则为假。

            【讨论】:

            • +1 有用的解释。有人可以评论number($v) = number($v)number($v) = $v 产生不同结果的情况吗?
            • @LarsH:我已经评论过这些案例。您能指出一个尚未讨论的案例吗?
            • 我的意思是有人可以列出number($v) = number($v)number($v) = $v 产生不同结果的情况吗?毫无疑问,这可以从您所写的内容中得出,但我没有看到您在哪里明确解决了这个问题。对不起,如果我很密集。 IOW,您的解决方案和@Oded 的/@Alejandro 的解决方案是否总是产生相同的结果?
            • @LarsH:我没有看过 Oded 的解决方案,因为它显然是我不想使用的东西。我认为 Al2jandro 的解决方案和我的解决方案对于 $v 的任何值给出相同的答案
            • @EricS,似乎只能通过购买 IEEE 标准来访问它...... Byt 看看这里:cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF。特别是,这一段: "IEEE 754 为所有涉及 NaN 的关系表达式赋值。在 C 的语法中,谓词 x != y 为 True 但所有其他谓词 x = y 和 x > y ,只要 x 或 y 或两者均为 NaN 时为 False"
            【解决方案7】:

            根据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>
            

            【讨论】:

            • 因为在 XPath 1.0 NaN 数字数据类型的值不等于任何数字值,并且如果至少一个参数是数字数据类型,那么另一个参数被转换为数字,这是最短数测试:number(MyNode)=MyNode
            • @Alejandro 的简短版本由于 = 运算符 (Required item type of first operand of '=' is numeric; supplied value has item type xs:string;) 上的类型不匹配而在 XPath 2.0 中完全失败,但 Dimitre 的解决方案工作正常。
            猜你喜欢
            • 2016-04-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-09-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多