2010-10-04 5 views

Répondre

98

Test de la valeur par rapport NaN:

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

Ceci est une version plus courte (merci @Alejandro):

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

Parce que dans XPath 1.0 'valeur NaN' du nombre le type de données n'est pas égal à une valeur numérique et pour la comparaison si au moins un argument est une donnée numérique, l'autre est converti en nombre, c'est le test numérique le plus court: 'number (MyNode) = MyNode' –

+7

La version courte de @Alejandro échoue complètement avec XPath 2.0 en raison de la non-concordance e = operator ('Type d'élément requis du premier opérande de '=' est numérique; la valeur fournie a le type d'élément xs: string; '), la solution de Dimitre fonctionne cependant bien. – Lucero

47

Le chemin le plus court possible de tester si la valeur contenue dans une $v variable peut être utilisé comme un nombre est:

number($v) = number($v) 

Vous devez uniquement remplacer le $v ci-dessus par l'expression dont vous voulez tester la valeur.

Explication:

number($v) = number($v) est évidemment vrai, si $v est un nombre ou une chaîne qui représente un nombre.

Il est vrai aussi pour une valeur booléenne, parce qu'un number(true()) est 1 et number(false) est 0.

Chaque fois que $v ne peut pas être utilisé comme un numéro, puis number($v) est NaN

et NaN est pas égal à toute autre valeur, même à elle-même.

Ainsi, l'expression ci-dessus est vraie uniquement pour $v dont la valeur peut être utilisée comme un nombre et false dans le cas contraire.

+1

+ 1 explication utile. Quelqu'un peut-il commenter les cas où 'number ($ v) = number ($ v)' donne un résultat différent de 'number ($ v) = $ v'? – LarsH

+0

@LarsH: J'ai déjà commenté ces cas.Pouvez-vous signaler encore un cas non discuté? –

+0

Je voulais dire que quelqu'un pourrait citer les cas où 'number ($ v) = number ($ v)' donne un résultat différent de 'number ($ v) = $ v'? Sans doute cela est dérivé de ce que vous avez écrit, mais je ne vois pas où vous avez abordé cette question explicitement. Désolé si je suis dense. IOW, votre solution et la solution de @ Oded/@ Alejandro donnent-elles toujours les mêmes résultats? – LarsH

14

Je n'essaie pas de fournir une autre solution alternative, mais une "méta-vue" à ce problème.

Les réponses déjà fournies par Oded et Dimitre Novatchev sont correctes, mais ce que les gens pourraient vraiment vouloir dire par l'expression «la valeur est un nombre» est, comment dirais-je, ouvert à l'interprétation. D'une certaine manière, tout se résume à cette question bizarre: "comment voulez-vous exprimer vos valeurs numériques?"

fonction XPath number() Les numéros de processus qui ont

  • attaque possible ou espaces à la fin
  • précédentes signe caractère uniquement sur des valeurs négatives
  • de points comme un séparateur décimal (en option pour les nombres entiers
  • tous les autres caractères de la plage [0-9]

Notez que cela ne comprend pas les expressions de valeurs numériques

  • sont exprimés sous forme exponentielle (par exemple 12.3E45)
  • peut contenir le caractère de signe pour les valeurs positives
  • ont une distinction entre zéro
  • positifs et négatifs comprennent la valeur pour l'infini positif ou négatif

Ce ne sont pas juste fait des critères. Un élément dont le contenu est conforme au schéma d'une valeur valide xs:float peut contenir l'une des caractéristiques mentionnées ci-dessus. Pourtant number() renverrait la valeur NaN.

Alors répondez à votre question "Comment puis-je vérifier avec XPath si une valeur de noeud est un nombre?" est soit "Utiliser les solutions déjà mentionnées en utilisant number()" ou "avec une seule expression XPath 1.0, vous ne pouvez pas". Pensez aux formats de nombres possibles que vous pourriez rencontrer, et si nécessaire, écrivez une sorte de logique pour la validation/l'analyse des nombres. Dans le traitement XSLT, cela peut être fait avec quelques modèles supplémentaires appropriés, par exemple.

PS. Si vous ne vous préoccupez chiffres non nuls, le test le plus court est

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

+1 Une bonne explication détaillée des questions à l'origine de la question: qu'est-ce que le PO aurait pu signifier ou aurait signifié s'il avait su quoi demander? – LarsH

0

Vous pouvez toujours utiliser quelque chose comme ceci:

string(//Sesscode) castable as xs:decimal 

coulable est documenté par le W3C here.

9

Celui que je trouve très utile est la suivante:

<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

Il y a un opérateur de test de type étonnant dans XPath 2.0, vous pouvez utiliser:

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