Jak mogę sprawdzić, czy wartość węzła jest liczbą przy użyciu XPath?
Jakieś pomysły?
Przetestuj wartość względem NaN :
<xsl:if test="string(number(myNode)) != 'NaN'">
<!-- myNode is a number -->
</xsl:if>
To jest krótsza wersja (dzięki @Alejandro ):
<xsl:if test="number(myNode) = myNode">
<!-- myNode is a number -->
</xsl:if>
NaN
wartość typu danych liczba nie jest równa żadnej wartości liczbowej i dla porównania, jeśli co najmniej jeden argument to liczba wpisana, drugi jest rzutowany na liczbę, jest to test najkrótszej liczby:number(MyNode)=MyNode
Required item type of first operand of '=' is numeric; supplied value has item type xs:string;
), rozwiązanie Dimitre działa jednak dobrze.Najkrótszym możliwym sposobem sprawdzenia, czy wartość zawarta w zmiennej
$v
może być użyta jako liczba, to :Wystarczy zastąpić
$v
powyższe wyrażenie, którego wartość chcesz przetestować.Wyjaśnienie :
number($v) = number($v)
jest oczywiście prawdą, jeśli$v
jest liczbą lub łańcuchem reprezentującym liczbę.Dotyczy to również wartości logicznej, ponieważ a
number(true())
wynosi 1 inumber(false)
wynosi 0.Ilekroć
$v
nie można użyć jako liczby,number($v)
oznacza to NaNa NaN nie jest równe żadnej innej wartości, nawet sobie.
Zatem powyższe wyrażenie jest prawdziwe tylko dla
$v
którego wartość może być użyta jako liczba, a fałsz w przeciwnym razie.źródło
number($v) = number($v)
daje inny wyniknumber($v) = $v
?number($v) = number($v)
daje inny wyniknumber($v) = $v
? Bez wątpienia można to wyprowadzić z tego, co napisałeś, ale nie widzę, gdzie bezpośrednio odniosłeś się do tego pytania. Przepraszam, jeśli jestem gęsty. IOW, czy Twoje rozwiązanie i rozwiązanie @ Oded / @ Alejandro zawsze dają takie same wyniki?W XPath 2.0 jest niesamowity operator testu typu, którego możesz użyć:
<xsl:if test="$number castable as xs:double"> <!-- implementation --> </xsl:if>
źródło
Nie próbuję przedstawić innego alternatywnego rozwiązania, ale „meta spojrzenie” na ten problem.
Odpowiedzi udzielone już przez Odeda i Dimitre Novatcheva są poprawne, ale to, co ludzie naprawdę mogliby mieć na myśli, mówiąc „wartość to liczba”, jest, jak bym to powiedział, otwarte na interpretację.
W pewnym sensie wszystko sprowadza się do tego dziwnie brzmiącego pytania: „jak chcesz wyrazić swoje wartości liczbowe?”
Funkcja XPath
number()
przetwarza liczby, które mająZauważ, że nie obejmuje to wyrażeń dla wartości liczbowych that
To nie są tylko wymyślone kryteria. Element, którego treść jest zgodna ze schematem, ma prawidłową
xs:float
wartość, może zawierać dowolną z wyżej wymienionych cech. Jednaknumber()
zwróci wartośćNaN
.Zatem odpowiedz na pytanie „Jak mogę sprawdzić za pomocą XPath, czy wartość węzła to liczba?” to „Użyj już wspomnianych 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 walidacji / analizowania liczb. W ramach przetwarzania XSLT można to zrobić na przykład za pomocą kilku odpowiednich dodatkowych szablonów.PS. Jeśli zależy Ci tylko na liczbach niezerowych, najkrótszy test to
<xsl:if test="number(myNode)"> <!-- myNode is a non-zero number --> </xsl:if>
źródło
Ten, który uznałem za 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>
źródło
Zawsze możesz użyć czegoś takiego:
castable jest udokumentowane przez W3C tutaj .
źródło
Miałem do czynienia z 01 - który jest liczbą.
string(number($v)) != string($v)
dokonuje segregacjiźródło