2012-09-06 12 views
5

के लिए परीक्षण मैं बाहरी डेटा स्टोर से एक्सएमएल प्रतिक्रियाओं की एक श्रृंखला को पार्स कर रहा हूं। जिसके दौरान मुझे एक बच्चे नोड के अस्तित्व के लिए परीक्षण करना चाहिए और - यदि यह मौजूद है - इसके मूल्य का परीक्षण करें। प्राप्त करने के लिए कि मैं निम्नलिखित कोड है:स्कैला एक्सएमएल: नोड अस्तित्व और मूल्य

... 
    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 इस तरह के रूप में परिभाषित किया जाता है:

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

val name... लाइन पर "सरल अभिव्यक्ति के अवैध शुरुआत" की एक अनिर्दिष्ट त्रुटि में उपरोक्त कोड का परिणाम है। ईमानदार होने के लिए मैं एक स्कैला प्रोग्रामर या यहां तक ​​कि एक कार्यात्मक प्रोग्रामर नहीं हूं (हमेशा ओओ/अनिवार्य के लिए अधिक आंशिक था)। मैं केवल कुछ दिनों के लिए स्कैला का उपयोग कर रहा हूं और जावा और लैम्ब्डा ऑपरेटरों से जो कुछ जानता हूं, उसके आधार पर। दुर्भाग्य से, मेरे पास वास्तव में बैठने का समय नहीं है और वास्तव में स्कैला सीखना पसंद है जैसा मैं चाहता हूं। समय सीमा, हम सभी को मूर्ख बनाओ।

मुझे आशा है कि कोई भी एक नज़र डालें और मुझे कुछ बताएं कि क्या कुछ गलत है (जैसा कि मुझे यकीन है)। मैंने दिखाए गए कोड को सीमित करने की कोशिश की, जो मुझे आशा है, सवाल के लिए प्रासंगिक है। हालांकि, अगर कोई अतिरिक्त कोड की आवश्यकता है तो कृपया मुझे बताएं।

धन्यवाद

+0

मुझे लगता है कि मुझे यह स्पष्ट करना चाहिए कि उपर्युक्त बयान के लिए समझ का हिस्सा है। 'अगर (cond) 'उपज ब्लॉक के निष्पादन को निर्धारित करने के लिए माना जाता है। मैंने कोड पर विस्तृत जानकारी के लिए अपना उत्तर संपादित कर लिया है। संक्षिप्त प्रतिक्रिया के लिए – Cowan

उत्तर

1

एक्सएमएल यहां एक व्याकुलता है। समस्या यह है कि अगर अंत में (cond) एक गार्ड के रूप में कार्य नहीं कर रहा है, तो ऐसा लगता है कि यह चाहिए, संकलक सोचता है कि 'तो' भाग में एक नया शुरू होता है।

निम्न उदाहरण में:

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

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

आप सूची (6,8,10) मिल जाएगा के रूप में आप उम्मीद कर सकते।

का उपयोग

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

आप एक प्रतिवाद चेतावनी मिलना चाहिए, और

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

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

हो जाता है बस अपने जनरेटर के सामने वैल को दूर (Pattern1 '< -' Expr [गार्ड]), और आप सामान्य सेवा फिर से शुरू कर सकते हैं। यह मुझे लूप के लिए vals के बिना थोड़ा और अच्छी तरह से बहती है।

+0

यह सीधे सवाल से संबंधित सबसे अच्छा जवाब है। दुर्भाग्य से, इसने मुझे समस्या को फिर से सोचने और महत्वपूर्ण पुन: लिखने के लिए प्रेरित किया। – Cowan

0

if (cond) एक अभिव्यक्ति द्वारा पालन किया जाना चाहिए। स्कैला में, if जावा में टर्नरी ऑपरेटर की तरह अधिक है: यह एक अभिव्यक्ति है, एक बयान नहीं। एक परिवर्तनीय घोषणा एक अभिव्यक्ति नहीं है (जावा में), इसलिए आपके पास then भाग में val नहीं हो सकता है।

ईमानदारी से, मैं अनुमान लगा सकता हूं कि आप वहां क्या हासिल करना चाहते हैं, इसलिए मैं एक वाक्य रचनात्मक रूप से सही विकल्प का सुझाव नहीं दे सकता जो समझ में आता है। लेकिन अगर आप अधिक तर्क यह है कि cond पर निर्भर करता है है, तो आप यह एक ब्लॉक में डाल सकता है:

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

धन्यवाद। मैं भूल गया कि अगर कथन सशर्त ऑपरेटर के रूप में कार्य कर सकता है। हालांकि, इस मामले में मैं ऑपरेशन के लिए व्यापक के हिस्से के रूप में यदि कथन का उपयोग कर रहा हूं, जो मुझे विश्वास है (मैं बहुत गलत हो सकता हूं) इसे उपनगरीय ऑपरेटर से उपज बयान के लिए एक सशर्त आवश्यकता में बदल देता है। मैंने कोड के अधिक शामिल करने के लिए ऊपर दिए गए मेरे प्रश्न को संशोधित किया है। – Cowan

3

सबसे पहले, ध्यान दें कि (row \ "ResultDetectionConditionText")null नहीं हो सकता है अगर इस नाम का कोई बच्चों का अस्तित्व-यह सिर्फ किया जाएगा एक खाली NodeSeq (idiomatic Scala कोड null लौटने से बचने के लिए होता है, जैसा कि आपने शायद देखा है)। तो आपका वर्तमान कोड हमेशा Some लौटाएगा, जो शायद आप नहीं चाहते हैं। अपने != null से .nonEmpty को बदलना उस समस्या को ठीक करेगा।

इसके बाद, यहाँ सशर्त तर्क लेखन का अधिक संक्षिप्त तरीका है:

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

यह कहते हैं: एक NodeSeq कि सभी "Result..." नामित बच्चों में शामिल है मिलता है, यदि वे मौजूद हैं, और फिर जाँच करें कि NodeSeq एक नोड के लिए जिसमें टेक्स्ट "non-detect" है। तर्क बिल्कुल आपके जैसा नहीं है, क्योंकि हम व्यक्तिगत रूप से नोड्स के पाठ की जांच करते हैं, लेकिन यह वास्तव में फिट बैठता है जो मैं अनुमान लगाता हूं कि आपका इरादा भी बेहतर है-संभवतः आप इस तरह से कुछ पास नहीं करना चाहते हैं:

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

लेकिन यह आपके वर्तमान संस्करण में होगा।

लेकिन इनमें से कोई भी आपके "illegal start of simple expression" समस्या हल करता है-यह सिर्फ तर्क को ठीक करता है और कोड की सोलह लाइनों को तीन तक घटा देता है। यहां समस्या यह है कि आपको यह तय करने की आवश्यकता है कि आपके name क्या होना चाहिए यदि आपने जो परीक्षण अभी किया है, वह विफल हो जाता है।

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

लेकिन आप name उपयोग कर रहे हैं पर निर्भर करता है, कुछ अन्य दृष्टिकोण अधिक उपयुक्त हो सकता: सबसे स्पष्ट दृष्टिकोण का उपयोग करने के Option है।

+0

प्रतिक्रिया के लिए धन्यवाद और उन मुद्दों को इंगित करने के लिए धन्यवाद, मैं कोड में उन परिवर्तनों को लागू करूंगा। मैंने अपने प्रश्न को संपादित करने के लिए संपादित किया है कि यह सब व्यापक है - जिसके लिए मुझे लगता है (गलत हो सकता है) अगर कथन की तीसरी प्रकृति में परिवर्तन करता है। – Cowan

संबंधित मुद्दे