2010-10-04 13 views

Odpowiedz

98

Test wartość przed NaN:

<xsl:if test="string(number(myNode)) != 'NaN'"> 
    <!-- myNode is a number --> 
</xsl:if> 

Jest to krótsza wersja (dzięki @Alejandro):

<xsl:if test="number(myNode) = myNode"> 
    <!-- myNode is a number --> 
</xsl:if> 
+10

Ponieważ w XPath 1.0 'wartość NaN' numeru typ danych nie jest równy żadnej wartości liczbowej i dla porównania, jeśli przynajmniej jeden z argumentów jest danymi liczbowymi, to drugi jest rzutowany na numer, to jest test najkrótszego numeru: 'number (MyNode) = MyNode' –

+7

Skrócona wersja @Alejandro całkowicie zawiedzie z XPath 2.0 z powodu niedopasowania typu na th e = operator ('Wymagany typ elementu pierwszego operandu '=' jest numeryczny; dostarczona wartość ma typ elementu xs: string; '), rozwiązanie Dimitre działa jednak dobrze. – Lucero

47

najkrótszy możliwy sposób, aby sprawdzić, czy wartość zawarta w zmiennej $v puszka może być używana jako liczba::

number($v) = number($v) 

Wystarczy zastąpić powyższe $v wyrażeniem, którego wartość chcesz przetestować.

Wyjaśnienie:

number($v) = number($v) jest oczywiście prawdą, jeśli $v jest liczba lub ciąg, który reprezentuje liczbę.

Prawdą jest również dla wartości logicznej, bo number(true()) jest 1 i number(false) 0.

Ilekroć $v nie może być stosowany jako liczby, a następnie number($v) jest NaN

i NaN nie jest równa każda inna wartość, nawet sama dla siebie.

Tak więc powyższe wyrażenie jest prawdziwe tylko dla $v, którego wartość może być użyta jako liczba, a false w przeciwnym wypadku.

+1

+1 pomocne wyjaśnienie. Czy ktoś może komentować przypadki, w których 'liczba ($ v) = liczba ($ v)' daje inny wynik z 'number ($ v) = $ v'? – LarsH

+0

@LarsH: Już skomentowałem te przypadki.Czy możesz wskazać jeszcze jedną nieumiejętną sprawę? –

+0

Chodziło mi o to, że ktoś mógłby wymienić przypadki, w których 'liczba ($ v) = liczba ($ v)' daje inny wynik z 'number ($ v) = $ v'? Niewątpliwie wynika to z tego, co napisałeś, ale nie widzę, w którym miejscu skierowałeś to pytanie wprost. Przepraszam, jeśli jestem gęsty. IOW, czy Twoje rozwiązanie i rozwiązanie @ Odeda/@ Alejandro zawsze dają takie same wyniki? – LarsH

14

Nie próbuję zapewnić jeszcze jednego alternatywnego rozwiązania, ale "meta widzenia" tego problemu.

Odpowiedzi już dostarczone przez Odeda i Dimitre Novatcheva są poprawne, ale to, co ludzie mogą naprawdę znaczyć z wyrażeniem "wartość to liczba", to, jak by to powiedzieć, otwarte na interpretację.

W pewnym sensie wszystko to przychodzi do tego dziwacznie brzmiącego pytania: "jak chcesz wyrazić swoje wartości numeryczne?"

XPath funkcja number() procesy numery, które mają

  • możliwe czołowym lub końcowe spacje
  • poprzedzający znak charakter tylko na wartościach ujemnych
  • dot jako separatora dziesiętnego (opcjonalnie dla liczb całkowitych) Wszystkie inne postacie z zakresu [0-9]

Należy zauważyć, że nie dotyczy to wyrażenia Wartości liczbowe

  • wyrażanych w formie wykładniczej (np 12.3E45)
  • może zawierać znaku migowego dla wartości dodatnich
  • ma rozróżnienia między pozytywne i negatywne zerowy
  • zawierać wartość dla dodatniej lub ujemnej nieskończoności

Są nie tylko składa się kryteria. Element z treścią zgodną ze schematem ma prawidłową wartość, może zawierać dowolną z wyżej wymienionych cech. Jednak number() zwrócił wartość NaN.

Więc odpowiedź na pytanie "Jak mogę sprawdzić XPath, jeśli wartość węzła jest liczbą?" jest "Użyj już wymienionych rozwiązań używając number()" lub "z pojedynczym wyrażeniem XPath 1.0, nie możesz". Pomyśl o możliwych formatach liczb, które możesz napotkać, i jeśli to konieczne, napisz jakąś logikę do sprawdzania poprawności/liczby. W ramach przetwarzania XSLT można to zrobić na przykład za pomocą kilku odpowiednich dodatkowych szablonów.

PS. Jeśli tylko dbają o liczbie niezerowych, najkrótszy test jest

<xsl:if test="number(myNode)"> 
    <!-- myNode is a non-zero number --> 
</xsl:if> 
+1

+1 Dobre, szczegółowe wyjaśnienie kwestii leżących u podstaw pytania: co OP mógł mieć lub miałby na myśli, gdyby wiedział, o co pytać. – LarsH

0

Można zawsze używać coś takiego:

string(//Sesscode) castable as xs:decimal 

castable jest udokumentowany przez W3C here.

9

Jeden znalazłem bardzo przydatny jest następujący:

<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

Jest niesamowity operator badanie typu w XPath 2.0 można użyć:

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