2012-09-06 18 views
5

Bir dış veri deposundan bir dizi XML yanıtı ayrıştırıyorum. Bu sırada bir çocuk düğümün varlığını test etmeliyim ve eğer varsa - değerini test etmeliyim.Scala XML: düğüm varlığı ve değeri için test

... 
    val properties = for { 
    val row <- root \\ "ResultDescription" 
    val cond:Boolean = checkDetectionNode(row) match { 
     case Some(nodeseq) => { 
      val txt = nodeseq.text.toLowerCase 
      if (txt contains "non-detect") 
      false 
      else 
      true 
     } 
     case None => true 
    } 
    if (cond) 
    val name = (row \ "CharacteristicName").text 
    if (charNameList.exists(s => s == name) == false) 
    } yield { 
    getObservedProperty(name) match { 
     case Some(property) => { 
      charNameList = name :: charNameList 
      property 
     } 
    } 
    } 
... 

checkDetectionNode gibi tanımlanır: val name... satırında "basit ifade yasadışı bir başlangıç" belirsiz bir hata

private def checkDetectionNode(row: scala.xml.NodeSeq) : Option[scala.xml.NodeSeq] = { 
    if ((row \ "ResultDetectionConditionText") != null) 
    Some[scala.xml.NodeSeq]((row \ "ResultDetectionConditionText")) 
    else 
    None 
} 

Yukarıdaki kod sonucu aşağıdaki kod ulaşmak için. Dürüst olmak gerekirse, bir Scala programcısı ya da işlevsel bir programcı değilim (her zaman OO/emre göre daha kısmi). Scala'yı sadece birkaç günlüğüne kullanıyorum ve Java'dan ve lambda operatörlerinden bildiğim şeylerin çoğuna dayanıyordum. Ne yazık ki, gerçekten oturmak için zamanım yok ve Scala'yı dilediğim gibi yapmayı öğreniyorum. Son teslim tarihleri, hepimizi aptallar.

Birinin yanlış bir şey yapıp yapmadığımı (eğer olduğundan emin olduğum gibi) bana bir göz atabileceğini ve bana bildirebileceğini umuyorum. Gösterilen kodu, umduğum, soruyla alakalı olarak sınırlamaya çalıştım. Ancak, herhangi bir ek kod gerekip gerekmediğini lütfen bana bildirin.

Teşekkür

+0

Yukarıdaki açıklamaların bir açıklama anlaşmasının parçası olduğunu açıkça belirtmeliyim. “If (cond)”, getiri bloğunun yürütülmesini belirlemek için varsayalım. Kodu daha fazla incelemek için cevabımı düzenledim. – Cowan

cevap

1

xml burada bir dikkat dağıtıcı. Sorun sonunda (koşul) bekçi olarak hareket değilse, sadece olması gerektiği gibi, derleyici eğer 'o' kısmı yeni başlangıcı olduğunu düşünüyor görünüyor. Aşağıdaki örnekte

: Tahmin edebileceğiniz gibi

val l = List(1,2,3,4,5) 

val r = for { 
    i <- l 
     if (i > 2) 
    x <- Some(i * 2) 
    } yield x 

Eğer Listesi (6,8,10) elde edersiniz. Kullanılması

val r = for { 
    val i <- l if (i > 2) 
    val x <- Some(i * 2) 
    } yield x 

sana bir kullanımdan kaldırılması uyarı almak ve

val r = for { 
    val i <- l 
    if (i > 2) 
    val x <- Some(i * 2) 
    } yield x 

Basitçe Generator önünde val kaldırmak

error: illegal start of simple expression 
    val x <- Some(i * 2) 

alır gerektiğini (Desen1 '< -' Expr [Guard]) ve normal servise devam edebilirsiniz. Ayrıca bulduğum for döngüsündeki vals olmadan biraz daha güzel akar.

+0

Bu doğrudan soruyla ilgili en iyi cevaptır. Ne yazık ki, bu problemi yeniden düşünmemde ve önemli bir yeniden yazma yapmamı sağladı. – Cowan

0

if (cond) ifadesi ile takip edilmelidir. Scala'da, if, Java'daki üçlü operatöre benziyor: bir ifade değil, bir ifadedir. Bir değişken bildirimi (Java'da olduğu gibi) bir ifade değildir, yani bir then bölümünde bir val olamaz.

Dürüst olmak gerekirse, orada neye ulaşmak istediğinizi tahmin edemiyorum, bu yüzden anlamlı olan doğru sözdizimsel bir alternatif öneremiyorum. Eğer cond bağlıdır fazla mantığı Ama eğer bir blok koyabilirsiniz: Bu isimde hiçbir çocuk eğer (row \ "ResultDetectionConditionText")null olmayacak unutmayın, her şeyden

if (cond) { 
    val name = ... 
    // do more here 
} 
+0

Kısa yanıt için teşekkürler. If ifadesinin koşullu operatör olarak hareket edebileceğini unutmuşum. Ancak, bu durumda if ifadesini operasyon için kapsamlı bir parçanın parçası olarak kullanıyorum, inanıyorum ki (çok iyi anlaşılabilir), bir üçlü operatörden getiri bildirimi için koşullu bir gereklilik olarak değiştirir. Daha fazla kodu eklemek için yukarıdaki sorumu gözden geçirdim. – Cowan

3

Birinci mevcut-sadece olacak Boş bir NodeSeq (idiomatik Scala kodu, muhtemelen fark ettiğiniz gibi null'u iade etmeme eğilimindedir). Yani mevcut kodunuz her zaman istediğiniz gibi olmayan bir Some döndürecektir. != null öğenizin .nonEmpty olarak değiştirilmesi, bu sorunu giderecektir.

Sonraki, burada koşullu mantığı yazma daha özlü bir şekilde açıklanmıştır:

val cond = (row \ "ResultDetectionConditionText").exists(
    _.text.toLowerCase contains "non-detect" 
) 

Bu diyor ki: Varsa, "Result..." adlı tüm çocukları içeren bir NodeSeq olsun ve sonra bir düğüm için NodeSeq olmadığını kontrol Bu, "non-detect" numaralı metni içerir. Mantık, sizinkiyle tamamen aynı değildir, çünkü düğümlerin metnini tek tek kontrol ederiz, ama tahmin ettiğim şeye göre daha iyi niyetle uyuyor. Muhtemelen böyle bir şeyi testten geçmek istemiyorsunuz:

val row = <row> 
    <ResultDetectionConditionText>non-d</ResultDetectionConditionText> 
    <ResultDetectionConditionText>etect</ResultDetectionConditionText> 
</row> 

Ancak, geçerli sürümünüzde olacaktır.

Ancak bunların hiçbiri, "illegal start of simple expression" sorununuzu çözmez — yalnızca mantığı giderir ve on altı satırlık kodu üçe böler. Sorun şu ki, yaptığınız test başarısız olursa name'un ne olması gerektiğine karar vermeniz gerekiyor.

val name = if (cond) Some((row \ "CharacteristicName").text) else None 

Ama name nasıl kullandığınıza bağlı olarak, diğer bazı yaklaşım daha uygun olabilir: En belirgin yaklaşım Option kullanmaktır.

+0

yanıt için teşekkür ederiz ve bu konulara işaret ederek, kod bu değişiklikleri uygular. Sorumluluğumun tümünün (yanlış olabilir) if ifadesinin üçlü yapısını değiştirdiğine işaret ettiğimi belirtmek için sorumu düzenledim. – Cowan

İlgili konular