Düğüm değeri sayı ise XPath testi


89

Bir düğüm değerinin XPath kullanan bir sayı olup olmadığını nasıl kontrol edebilirim?

Herhangi bir fikir?

Yanıtlar:


124

Değeri NaN'ye karşı test edin :

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

Bu daha kısa bir versiyondur (teşekkürler @Alejandro ):

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

10
XPath 1.0'da NaNsayı veri türünün değeri herhangi bir sayı değerine eşit olmadığından ve karşılaştırma için en az bir bağımsız değişken yazılan sayı number(MyNode)=MyNode

10
@Alejandro'nun kısa versiyonu, = operator ( Required item type of first operand of '=' is numeric; supplied value has item type xs:string;) üzerindeki tip uyuşmazlığı nedeniyle XPath 2.0 ile tamamen başarısız oluyor, ancak Dimitre'nin çözümü iyi çalışıyor.
Lucero

61

Bir değişkendeki değerin $vsayı olarak kullanılıp kullanılamayacağını test etmenin mümkün olan en kısa yolu şudur :

number($v) = number($v)

$vYukarıdakileri yalnızca değerini test etmek istediğiniz ifadeyle değiştirmeniz gerekir .

Açıklama :

number($v) = number($v) açıkça doğrudur, eğer $vbir sayı veya bir sayıyı temsil eden bir dize .

Boole değeri için de doğrudur, çünkü a number(true())1'dir venumber(false) 0'dır.

Her ne zaman $vo zaman, bir sayı olarak kullanılamaznumber($v) NaN

ve NaN, kendisi için bile başka herhangi bir değere eşit değildir.

Bu nedenle, yukarıdaki ifade yalnızca $vdeğeri sayı olarak kullanılabilenler için doğrudur , aksi takdirde yanlıştır.


1
+1 faydalı açıklama. Birisi, number($v) = number($v)farklı bir sonuç verdiği durumlar hakkında yorum yapabilir number($v) = $vmi?
LarsH

@LarsH: Bu vakalar hakkında zaten yorum yapmıştım. Henüz tartışılmamış bir vakaya işaret edebilir misiniz?
Dimitre Novatchev

Demek istediğim, biri number($v) = number($v)farklı bir sonuç veren vakaları listeleyebilir number($v) = $vmi? Kuşkusuz bu, yazdıklarınızdan türetilebilir, ancak bu soruyu açıkça nerede ele aldığınızı göremiyorum. Yoğun oluyorsam özür dilerim. IOW, çözümünüz ve @ Oded'in / @ Alejandro'nun çözümü her zaman aynı sonuçları mı veriyor?
LarsH

@LarsH: Oded'in çözümüne bakmadım çünkü açıkça kullanmaktan hoşlanmayacağım bir şey. Sanırım Al2jandro'nun çözümü ve benimki çözüm, herhangi bir $ v değeri için aynı cevapları veriyor
Dimitre Novatchev

1
@EricS, IEEE standardına ancak satın alarak erişilebileceği görülüyor ... Byt buraya bir göz atabilir : cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF . Özellikle, bu paragraf: "IEEE 754, NaN içeren tüm ilişkisel ifadelere değerler atar. C'nin sözdiziminde, x! = Y koşulu Doğru, ancak diğerleri, x <y, x <= y, x == y, x> = y ve x> y, x veya y veya her ikisi de NaN olduğunda False olur "
Dimitre Novatchev

18

XPath 2.0'da kullanabileceğiniz harika bir tip test operatörü var:

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

15

Henüz başka bir alternatif çözüm sağlamaya çalışmıyorum, bu soruna bir "meta görünüm" sunmaya çalışıyorum.

Oded ve Dimitre Novatchev tarafından zaten verilen cevaplar doğrudur ancak insanların "değer bir sayıdır" cümlesiyle gerçekten kastettiği şey, bunu nasıl söylerim, yoruma açık olmasıdır.

Bir bakıma her şey kulağa tuhaf gelen şu soruya geliyor: "Sayısal değerlerinizi nasıl ifade etmek istiyorsunuz?"

XPath işlevi number(),

  • olası baştaki veya sondaki boşluk
  • önceki işaret karakteri yalnızca negatif değerlerde
  • ondalık ayırıcı olarak nokta (tamsayılar için isteğe bağlı)
  • [0-9] aralığındaki diğer tüm karakterler

Bunun sayısal değerler için ifadeler içermediğini unutmayın.

  • üstel biçimde ifade edilir (ör. 12.3E45)
  • pozitif değerler için işaret karakteri içerebilir
  • pozitif ve negatif sıfır arasında bir fark vardır
  • pozitif veya negatif sonsuzluk için değer ekleyin

Bunlar sadece uydurma kriterler değildir. Şemaya göre geçerli bir xs:floatdeğer olan içeriğe sahip bir öğe , yukarıda belirtilen özelliklerden herhangi birini içerebilir. Yine number()de değer döndürür NaN.

Öyleyse sorunuzu yanıtlayın "Bir düğüm değerinin sayı olup olmadığını XPath ile nasıl kontrol edebilirim?" "Daha önce bahsedilen çözümleri kullan number()" veya "tek bir XPath 1.0 ifadesi ile kullanamazsınız". Karşılaşabileceğiniz olası sayı biçimlerini düşünün ve gerekirse, doğrulama / sayı ayrıştırma için bir tür mantık yazın. XSLT işlemede bu, örneğin birkaç uygun ekstra şablonla yapılabilir.

PS. Yalnızca sıfır olmayan sayıları önemsiyorsanız, en kısa test

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

1
+1 Sorunun arkasındaki sorunların iyi ayrıntılı açıklaması: Ne soracağını bilseydi OP'nin ne demek istediği veya ne anlama geleceği.
LarsH

9

Çok yararlı bulduğum şey şudur:

<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

Her zaman böyle bir şey kullanabilirsiniz:

string(//Sesscode) castable as xs:decimal

castable burada W3C tarafından belgelenmiştir .


1

Sayısal olan 01 ile uğraşıyorum.

string(number($v)) != string($v) ayrımı yapar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.