2010-10-04 3 views

ответ

98

Тест значение против 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> 
+10

Поскольку в XPath 1.0 'NaN' значение числа тип данных не равен ни одному значению числа и для сравнения, если хотя бы один аргумент вводит числовые данные, а другой - в число, это кратчайший номер теста: 'number (MyNode) = MyNode' – 2010-10-04 14:13:13

+7

Краткая версия @Alejandro полностью терпит неудачу с XPath 2.0 из-за несоответствия типа на th e = operator ('Обязательный тип элемента первого операнда '=' является числовым; поставляемое значение имеет тип элемента xs: string; '), решение Dimitre работает отлично. – Lucero

47

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

number($v) = number($v) 

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

Объяснение:

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

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

Всякий раз, когда $v не может быть использован в качестве числа, то number($v) является НЭН

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

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

+1

+1 полезный информация. Может ли кто-нибудь прокомментировать случаи, когда 'number ($ v) = number ($ v)' дает другой результат из 'number ($ v) = $ v'? – LarsH

+0

@LarsH: Я уже прокомментировал эти случаи.Можете ли вы указать еще на нерассмотренный случай? –

+0

Я имел в виду, может кто-нибудь перечислить случаи, когда 'number ($ v) = number ($ v)' дает другой результат от 'number ($ v) = $ v'? Несомненно, это вытекает из того, что вы написали, но я не вижу, где вы прямо решили этот вопрос. Извините, если я плотный. IOW, ваше решение и решение @ Oded's/@ Alejandro всегда дают одинаковые результаты? – LarsH

14

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

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

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

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

+1 Хорошее подробное объяснение вопросов, стоящих за вопросом: что мог бы подразумевать OP или имел бы смысл, если бы он знал, что спросить. – LarsH

0

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

string(//Sesscode) castable as xs:decimal 

литьевой документируется W3C here.

9

Один я нашел очень полезным является следующее:

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

Там удивительное испытание типа оператора в XPath 2.0 вы можете использовать:

<xsl:if test="$number castable as xs:double"> 
    <!-- implementation --> 
</xsl:if> 
Смежные вопросы