webentwicklung-frage-antwort-db.com.de

XPath-Test, ob der Knotenwert number ist

Wie kann ich mithilfe von XPath überprüfen, ob ein Knotenwert eine Zahl ist?

Irgendwelche Ideen?

86
Harold SOTA

Teste den Wert gegen NaN :

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

Dies ist eine kürzere Version (danke @ Alejandro ):

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

Der kürzeste Weg zu testen, ob der in einer Variablen enthaltene Wert $v Als Zahl verwendet werden kann, ist:

number($v) = number($v)

Sie müssen nur das obige $v Durch den Ausdruck ersetzen, dessen Wert Sie testen möchten.

Erklärung:

number($v) = number($v) ist offensichtlich wahr, wenn $v eine Zahl oder eine Zeichenfolge ist, die eine Zahl darstellt.

Dies gilt auch für einen Booleschen Wert, da number(true()) 1 ist und number(false) 0 ist.

Wenn $v Nicht als Zahl verwendet werden kann, ist number($v) NaN

und NaN ist nicht gleich einem anderen Wert, auch nicht für sich.

Daher gilt der obige Ausdruck nur für $v, Dessen Wert als Zahl verwendet werden kann, und ansonsten für false.

54

In XPath 2.0 gibt es einen erstaunlichen Typentest-Operator, den Sie verwenden können:

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

Ich versuche nicht, eine weitere alternative Lösung anzubieten, sondern eine "Meta-Sicht" auf dieses Problem.

Die bereits von Oded und Dimitre Novatchev gegebenen Antworten sind richtig, aber was die Leute mit der Phrase "Wert ist eine Zahl" wirklich meinen könnten, ist, wie ich es sagen würde, offen für Interpretationen.

In gewisser Weise kommt alles auf diese bizarr klingende Frage: "Wie möchten Sie Ihre numerischen Werte ausdrücken?"

XPath-Funktion number() verarbeitet Zahlen, die haben

  • möglicherweise führendes oder nachfolgendes Leerzeichen
  • vorzeichen nur bei negativen Werten
  • Punkt als Dezimaltrennzeichen (optional für Ganzzahlen)
  • alle anderen Zeichen aus dem Bereich [0-9]

Beachten Sie, dass dies keine Ausdrücke für numerische Werte enthält, die

  • werden in Exponentialform ausgedrückt (z. B. 12.3E45)
  • kann ein Vorzeichen für positive Werte enthalten
  • unterscheiden zwischen positiver und negativer Null
  • wert für positive oder negative Unendlichkeit einschließen

Dies sind nicht nur erfundene Kriterien. Ein Element mit einem Inhalt, der gemäß Schema ein gültiger Wert xs:float Ist, kann eines der oben genannten Merkmale enthalten. Dennoch würde number() den Wert NaN zurückgeben.

Beantworten Sie also Ihre Frage "Wie kann ich mit XPath überprüfen, ob ein Knotenwert eine Zahl ist?" lautet entweder "Verwenden Sie bereits erwähnte Lösungen mit number()" oder "Mit einem einzelnen XPath 1.0-Ausdruck können Sie nicht". Denken Sie über die möglichen Zahlenformate nach und schreiben Sie bei Bedarf eine Logik für die Validierung/Analyse von Zahlen. Innerhalb der XSLT-Verarbeitung kann dies beispielsweise mit wenigen geeigneten zusätzlichen Vorlagen erfolgen.

PS. Wenn Sie sich nur für Zahlen ungleich Null interessieren, ist der kürzeste Test

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

Das, was ich sehr nützlich fand, ist das Folgende:

<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

Sie könnten immer so etwas verwenden:

string(//Sesscode) castable as xs:decimal

castable wird von W3C dokumentiert hier .

1
Martti