2010-10-04 19 views

risposta

98

Prova valore contro NaN:

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

Questa è una versione più corta (grazie @Alejandro):

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

Perché in XPath 1.0 'valore NaN' del numero il tipo di dati non è uguale a nessun valore numerico e per il confronto se almeno un argomento è il numero di dati digitato, l'altro viene convertito in numero, questo è il test del numero più breve: 'number (MyNode) = MyNode' –

+7

La versione breve di @ Alejandro fallisce completamente con XPath 2.0 a causa della mancata corrispondenza di tipo su th e = operator ('Il tipo di elemento richiesto del primo operando di '=' è numerico; il valore fornito ha il tipo di elemento xs: string; '), la soluzione di Dimitre funziona comunque. – Lucero

47

La via più breve possibile testare se il valore contenuto in una variabile $v può essere usato come un numero è:

number($v) = number($v) 

Hai solo bisogno di sostituire il $v sopra con l'espressione il cui valore si desidera testare.

Spiegazione:

number($v) = number($v) è ovviamente vero, se $v è un numero o una stringa che rappresenta un numero.

E 'vero anche per un valore booleano, perché un number(true()) è 1 e number(false) è 0.

Ogni volta $v non può essere utilizzato come un numero, quindi number($v) è NaN

e NaN non è uguale a qualsiasi altro valore, anche a se stesso.

Così, l'espressione sopra è vero solo per $v cui valore può essere utilizzato come numero e false altrimenti.

+1

+1 spiegazione utile. Qualcuno può commentare casi in cui 'number ($ v) = number ($ v)' produce un risultato diverso da 'number ($ v) = $ v'? – LarsH

+0

@LarsH: ho già commentato questi casi.Puoi indicare ancora un caso non discusso? –

+0

Intendo dire che qualcuno potrebbe elencare i casi in cui 'number ($ v) = numero ($ v)' produce un risultato diverso da 'number ($ v) = $ v'? Senza dubbio è derivabile da ciò che hai scritto, ma non vedo dove hai indirizzato questa domanda esplicitamente. Scusate se sono troppo denso. IOW, la tua soluzione e la soluzione di @ Oded/@ Alejandro danno sempre gli stessi risultati? – LarsH

14

Non sto cercando di fornire una soluzione ancora un'altra alternativa, ma una "meta vista" a questo problema.

Le risposte già fornite da Oded e Dimitre Novatchev sono corrette ma ciò che le persone potrebbero realmente significare con la frase "il valore è un numero" è, come direi, aperto all'interpretazione.

In un certo senso tutto arriva a questa bizzarra domanda: "come si desidera esprimere i valori numerici?"

XPath funzione number() processi numeri che hanno

  • possibile iniziale o finale spazi
  • carattere precedente segno solo su valori negativi
  • dot come un separatore decimale (facoltativo per gli interi
  • tutti gli altri caratteri nell'intervallo [0-9]

noti che questo non include espressioni per valori numerici

  • sono espressi in forma esponenziale (ad esempio 12.3E45)
  • può contenere caratteri segno per valori positivi
  • hanno una distinzione tra positivo e negativo nullo
  • includono valore infinito positivo o negativo

Questi non sono solo costituiti criteri. Un elemento con contenuto conforme allo schema un valore valido xs:float potrebbe contenere una delle caratteristiche sopra menzionate. Tuttavia number() restituirebbe il valore NaN.

Quindi rispondi alla tua domanda "Come posso verificare con XPath se il valore di un nodo è il numero?" è "Utilizza soluzioni già menzionate usando number()" o "con una sola espressione XPath 1.0, non puoi". Pensa ai possibili formati numerici che potresti incontrare e, se necessario, scrivi una sorta di logica per la validazione/analisi del numero. Nell'elaborazione XSLT, questo può essere fatto con pochi modelli extra adatti, per esempio.

PS. Se vi interessa soltanto i numeri diversi da zero, il test più breve è

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

+1 Buona spiegazione dettagliata delle questioni alla base della domanda: cosa avrebbe potuto significare o avrebbe voluto dire l'OP se avesse saputo cosa chiedere. – LarsH

0

Si può sempre usare qualcosa di simile a questo:

string(//Sesscode) castable as xs:decimal 

castable è documentato dal W3C here.

9

Quello che ho trovato molto utile è la seguente:

<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

C'è un operatore stupefacente tipo di test in XPath 2.0 è possibile utilizzare:

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