Проверка XPath, если значение узла является числом - PullRequest
86 голосов
/ 04 октября 2010

Как проверить, является ли значение узла числом, используя XPath?

Есть идеи?

Ответы [ 6 ]

117 голосов
/ 04 октября 2010

Проверьте значение по 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>
54 голосов
/ 04 октября 2010

Кратчайший из возможных способов проверить, может ли значение, содержащееся в переменной $v, использоваться в качестве числа: :

number($v) = number($v)

Вам нужно только заменить $v выше на выражение, значение которого вы хотите проверить.

Объяснение :

number($v) = number($v) очевидно верно, если $v - это число или строка, представляющая число.

Это верно и для логического значения, поскольку number(true()) равно 1, а number(false) равно 0.

Если $v нельзя использовать как число, тогда number($v) - это NaN

и NaN не равно ни одному другому значению, даже самому себе.

Таким образом, вышеприведенное выражение верно только для $v, значение которого может быть использовано как число, и false в противном случае.

17 голосов
/ 01 февраля 2013

В XPath 2.0 есть замечательный оператор тестирования типов, который вы можете использовать:

<xsl:if test="$number castable as xs:double">
    <!-- implementation -->
</xsl:if>
15 голосов
/ 04 октября 2010

Я не пытаюсь предложить еще одно альтернативное решение, но "мета-взгляд" на эту проблему.

Ответы, уже предоставленные Одедом и Димитром Новатчевым, верны, но то, что на самом деле могут означать люди под фразой «значение есть число», как бы это сказать, открыто для интерпретации.

Вкак все это сводится к этому странному звучанию вопроса: «как вы хотите выразить свои числовые значения?»

Функция 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>
9 голосов
/ 02 марта 2012

Мне показалось очень полезным следующее:

<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>
1 голос
/ 25 ноября 2011

Вы всегда можете использовать что-то вроде этого:

string(//Sesscode) castable as xs:decimal

castable документируется W3C здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...