ノード値が数値かどうかのXPathテスト


89

XPathを使用してノード値が数値であるかどうかを確認するにはどうすればよいですか?

何か案は?

回答:


124

NaNに対して値をテストします。

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

これは短いバージョンです(@Alejandroに感謝):

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

10
XPathの1.0ためNaN:少なくとも一つの引数が数値データが入力された場合に数データ型の値は、任意の数の値との比較のために等しくない、他の数にキャストされ、これは最短番号試験であるnumber(MyNode)=MyNode

10
=演算子(Required item type of first operand of '=' is numeric; supplied value has item type xs:string;)の型の不一致により、@ Alejandroによる短いバージョンはXPath 2.0で完全に失敗しますが、Dimitre のソリューションは正常に機能します。
Lucero

60

変数に含まれている値を数値$vとして使用できるかどうかをテストする最も簡単な方法は次のとおりです

number($v) = number($v)

$v上記の値を、テストする値を持つ式に置き換えるだけです。

説明

number($v) = number($v)$v数値、または数値を表す文字列の場合は、明らかにtrue です。

a number(true())は1でnumber(false)あり、0 であるため、ブール値にも当てはまります。

$v数値として使用できない場合はいつでも、number($v)NaN

NaNは、それ自体であっても、他の値とは等しくありません。

したがって、上記の式は$v、値を数値として使用できる場合にのみtrue になり、それ以外の場合はfalseになります。


1
+1役立つ説明。誰かnumber($v) = number($v)が別の結果をもたらす場合についてコメントできますかnumber($v) = $v
LarsH

@LarsH:これらのケースについてはすでにコメントしました。まだ議論されていないケースを指摘できますか?
Dimitre Novatchev

私は誰かnumber($v) = number($v)が別の結果を生み出すケースをリストアップできるnumber($v) = $vだろうか?間違いなく、それはあなたが書いたものから導き出せるものですが、私がこの質問に明示的に対処した場所はわかりません。私が密集している場合は申し訳ありません。IOW、あなたのソリューションと@ Oded's / @ Alejandroのソリューションは常に同じ結果をもたらしますか?
LarsH

@LarsH:Odedのソリューションはまだ使用したくないので、これまで見ていない。私はAl2jandroのソリューションと鉱山ソリューションは$ Vの任意の値に同じ答えを与えると思います
Dimitre Novatchev

1
@EricS、それを購入することによってのみIEEE標準にアクセスできるようです... たぶん、ここを見てください:cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF。特に、この段落:「IEEE 754は、NaNを含むすべての関係式に値を割り当てます。Cの構文では、述語x!= yはTrueですが、その他すべてのx x <y、x <= y、x == y、 x> = yおよびx> y、xまたはyまたは両方がNaNである場合は常にFalseです "
Dimitre Novatchev

18

XPath 2.0には、使用できる驚くべき型テスト演算子があります。

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

15

私はさらに別の代替ソリューションを提供しようとしているのではなく、この問題の「メタビュー」を提供しています。

OdedとDimitre Novatchevによってすでに提供されている答えは正しいですが、「値は数値」というフレーズで実際に人々が意味する可能性があるのは、どのように言うか、解釈に対してオープンです。

ある意味で、それはすべてこの奇妙に聞こえる質問になります: 「数値をどのように表現したいですか?」

XPath関数number()は、

  • 可能性のある先頭または末尾の空白
  • 負の値でのみ先行する符号文字
  • ドットとしての(整数の場合はオプション)
  • 範囲[0-9]の他のすべての文字

これには、以下の数値の式は含まれません。

  • 指数形式で表されます(例:12.3E45)
  • 正の値の記号文字を含めることができます
  • 正と負のゼロを区別する
  • 正または負の無限大の値を含める

これらは単なる基準ではありません。スキーマに従って有効なxs:float値の内容を持つ要素には、上記の特性のいずれかが含まれる場合があります。まだnumber()値を返しますNaN

それで、「ノード値が数値である場合、XPathで確認するにはどうすればよいですか?」という質問に答えてください。「を使用してすでに説明したソリューションを使用するnumber()」または「単一のXPath 1.0式では使用できない」のいずれかです。発生する可能性のある可能性のある数値形式について考え、必要に応じて、検証/数値解析のためのある種のロジックを記述します。XSLT処理内では、これは、たとえばいくつかの適切な追加テンプレートを使用して実行できます。

PS。ゼロ以外の数値のみを考慮する場合、最短のテストは

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

1
+1質問の背後にある問題についての詳細な説明:OPが何を尋ねるべきかを知っていれば、OPが何を意味し、何を意味するのか
LarsH

9

私が非常に便利だと思ったのは次のとおりです。

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

2

あなたはいつもこのようなものを使うことができます:

string(//Sesscode) castable as xs:decimal

castableはW3Cによってここに文書化されています


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.