web-dev-qa-db-fra.com

Test XPath si la valeur du noeud est un nombre

Comment puis-je vérifier si une valeur de nœud est un nombre utilisant XPath?

Des idées?

86
Harold SOTA

Testez la valeur contre 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>
119
Oded

Le moyen le plus court possible de tester si la valeur contenue dans une variable $v Peut être utilisé sous la forme d'un nombre:

number($v) = number($v)

Il vous suffit de 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 représentant un nombre.

Cela vaut également pour une valeur booléenne, car number(true()) vaut 1 et number(false) vaut 0.

Chaque fois que $v Ne peut pas être utilisé sous forme de nombre, alors number($v) est NaN

et NaN n'est égal à aucune autre valeur, même à elle-même.

Ainsi, l'expression ci-dessus n'est vraie que pour $v, Dont la valeur peut être utilisée sous forme de nombre, et faux sinon.

54

Il existe un opérateur de test de type incroyable dans XPath 2.0 que vous pouvez utiliser:

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

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

Les réponses déjà fournies par Oded et Dimitre Novatchev sont correctes, mais ce que les gens pourraient réellement vouloir dire avec la phrase "la valeur est un nombre" est, comment dirais-je, ouvert à interprétation.

D'une certaine manière, tout cela revient à cette question qui a l'air bizarre: "comment voulez-vous exprimer vos valeurs numériques?"

XPath function number() traite les nombres qui ont

  • possibles espaces de début ou de fin
  • caractère de signe précédent uniquement sur les valeurs négatives
  • point comme séparateur décimal (facultatif pour les entiers)
  • tous les autres caractères de la plage [0-9]

Notez que cela n'inclut pas les expressions pour les valeurs numériques

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

Ce ne sont pas simplement des critères inventés. Un élément dont le contenu est conforme au schéma, une valeur xs:float Valide peut contenir l’une des caractéristiques mentionnées ci-dessus. Cependant, 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 "Utilisez 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 vous souciez uniquement des nombres non nuls, le test le plus court est

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

Celui que j'ai trouvé très utile est le suivant:

<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>
9
jkpd

Vous pouvez toujours utiliser quelque chose comme ceci:

string(//Sesscode) castable as xs:decimal

castable est documenté par le W3C ici .

1
Martti