2012-02-06 7 views
5

मेरे पास एक क्लाइंट है जो एक XML फ़ीड भेजता है जिसे मैं निम्नलिखित कोड का उपयोग करके पार्स करता हूं। यह कोड काम करता है।एक LINQ के साथ एक विशिष्ट को अनदेखा कैसे करें जहां खंड?

reviews = from item in xmlDoc.Descendants("node") 
          select new ForewordReview() 
          { 
           PubDate = (string)item.Element("created"), 
           Isbn = (string)item.Element("isbn"), 
           Summary = (string)item.Element("review") 
          }; 

मेरी सभी "समीक्षा" प्राप्त करने के बाद मैंने एक सूची के रूप में IENumerable डाला और इसे वापस कर दिया। मूल रूप से, मैं उनके एक्सएमएल जो इस तरह देखने के लिए प्रयोग किया जाता है पार्स करने के लिए एक अच्छा और आसान समय हो रही थी:

<reviews> 
    <node> 
     <created>01-01-1900</created> 
     <ISBN>12345657890123</ISBN> 
     <Review>This is a nice and silly book</Review> 
    </node> 
    <node> 
     <created>01-01-2011</created> 
     <ISBN>1236245234554</ISBN> 
     <Review>This is a stupid book</Review> 
    </node> 
    <node> 
     <created>12-06-1942</created> 
     <ISBN>1234543234577</ISBN> 
     <Review>This is a old, naughty book</Review> 
    </node> 
</reviews> 

वे है, हालांकि, उनके स्कीमा बदल गया है, जो मैं पहुँच नहीं है, और अब अपने एक्सएमएल है अंत में एक अंतिम <node> टैग में जोड़ना जिसमें मेरे द्वारा देखे जाने वाले घटित तत्व शामिल नहीं हैं, और इसलिए, मेरे पिछले टैग पर मेरा पार्सिंग टूट जाता है और मैंने अपवाद फेंक दिया। यहाँ एक उदाहरण है:

<reviews> 
    <node> 
     <created>01-01-1900</created> 
     <ISBN>12345657890123</ISBN> 
     <Review>This is a nice and silly book</Review> 
    </node> 
    <node> 
     <created>01-01-2011</created> 
     <ISBN>1236245234554</ISBN> 
     <Review>This is a stupid book</Review> 
    </node> 
    <node> 
     <created>12-06-1942</created> 
     <ISBN>1234543234577</ISBN> 
     <Review>This is a old, naughty book</Review> 
    </node> 
    <node> 
     <count>4656</count> 
    </node> 
</reviews> 

मैं अगर वहाँ इस अंतिम टैग की अनदेखी करने के लिए एक रास्ता है पता करने की जरूरत है (इसकी हमेशा दस्तावेज़ के अंत में) भले ही यह अन्य सभी "नोड" के रूप में एक ही नाम है टैग मैं देख रहा हूँ। मेरे पास कोड के इस ब्लॉक के चारों ओर पकड़ने का प्रयास है, लेकिन अगर यह इस त्रुटि को देखता है तो यह अच्छी समीक्षाओं की सूची वापस नहीं करता है।

धन्यवाद दोस्तों।

+1

शायद 'जहां आइटम। एलिमेंट ("गिनती") == null' _ (या अन्य मार्ग "बनाया गया"! = Null) _ – ordag

+0

@ordag मैं वास्तव में आपके समाधान में कुछ नल जांच के साथ भी शामिल करता हूं डेलट्री सुझाव से। धन्यवाद। –

उत्तर

1

जोड़ने अशक्त जाँच

PubDate = (string)(item.Element("created") ?? ""), 
Isbn = (string)(item.Element("isbn") ?? ""), 
Summary = (string)(item.Element("review") ?? "") 

हमेशा सब कुछ आपको बस इतना करना अशक्त चेकिंग जोड़ें। बस अच्छा अभ्यास। इस मामले में, यह इस त्रुटि को समाप्त कर देगा, लेकिन संभावित रूप से आपके प्रोग्राम में एक त्रुटि को फसल कर देगा जहां आप मानते हैं कि ये तार खाली नहीं हैं, इसलिए सुनिश्चित करें और बाद में भी जांच लें।

+0

तो अगर यह अजीब नोड से मुकाबला करता है, तो यह किसी ऑब्जेक्ट में पबडेट, आईएसबीएन और सारांश लोड करेगा और प्रत्येक खाली स्ट्रिंग देगा? यदि मामला है तो मैं निश्चित रूप से उस डाउनस्ट्रीम को संभाल सकता हूं। –

+0

बिल्कुल। string.Empty एक बेहतर विकल्प हो सकता है, लेकिन यह सिर्फ एक त्वरित लेखन – deltree

+0

@deltree था: मुझे लगता है कि "" स्ट्रिंग से अधिक पठनीय है। लक्षण। –

4

यह हमेशा पिछले नोड है,

var nodes = xmlDoc.Descendants("node"); 
reviews = nodes.Take(nodes.Count() - 1).Select(...); 
+0

यह हमेशा अंतिम "नोड" है लेकिन अंतिम तत्व नहीं है। "समीक्षा" तत्व मूल तत्व है। क्या वो वजह बन रही हे? –

+0

@fullNelson: यह अंतिम तत्व को छोड़कर "नोड" नामक सभी तत्वों को ले जाएगा। क्या आपने कोड पढ़ा था? –

+0

मैंने इसे पढ़ा था। मैं वाक्यविन्यास की इस शैली का कभी भी उपयोग नहीं करता (जैसा कि मैं linq के लिए नया हूं) इसलिए मुझे नहीं पता कि यह कैसे काम करता है। –

1

आप नोड्स की संख्या की गणना कर सकता है और उसके बाद के इस अधिभार का उपयोग कहाँ है, जो भी एक सूचकांक संख्या गुजरता है: (http://msdn.microsoft.com/en-us/library/bb549418.aspx)

public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source, 
Func<TSource, int, bool> predicate) 

तो, कुछ इस तरह:

var count = xmlDoc.Descendants("node").Count(); 
xmlDoc.Descendants("node").Where((node,index) => index < count-1).Select(..) 
+0

यही है 'टेक' के लिए है। –

+0

मुझे यकीन है कि मुझे पता है कि यहां क्या हो रहा है, लेकिन मेरे कोड से वाक्यविन्यास में अंतर मुझे फेंकता है। मुझे लगता है कि आप और मैटी क्या उपयोग कर रहे हैं एक 'डॉट' नोटेशन है। मेरे लिए, मुझे नहीं पता कि इस फ़िल्टर को कहां से पहले कथन में जोड़ना है। –

+0

@fullnelson समान कथन लिनक्स सिंटैक्स का उपयोग करके अधिक आसानी से लिखे/पढ़े जाते हैं और कुछ विस्तार विधियों (ऊपर के रूप में) का उपयोग करके अधिक आसानी से लिखे/पढ़ते हैं। यह जानना अच्छा है कि linq कथन सीधे विस्तार विधियों में अनुवाद किया जा सकता है। – MichaelvR

2

कुछ इस तरह चाल करना चाहिए:

var reviews = from item in xmlDoc.Descendants("node").Where(x => x.Element("created") != null) 
select new 
{ 
    PubDate = (string)item.Element("created"), 
    Isbn = (string)item.Element("isbn"), 
    Summary = (string)item.Element("review") 
}; 

आप यदि आप चाहें तो अन्य तत्वों के लिए अतिरिक्त शून्य जांच कर सकते हैं।

0

आप वहां "जहां" खंड फेंक सकते हैं।

reviews = from item in xmlDoc.Descendants("node") where item.Descendants().Any(n => n.Name == "Review") 
         select new ForewordReview() 
         { 
          PubDate = (string)item.Element("created"), 
          Isbn = (string)item.Element("isbn"), 
          Summary = (string)item.Element("review") 
         }; 

यह नमूना सिर्फ एक चाइल्ड नोड "समीक्षा" कहा जाता है के लिए जाँच की जाएगी, तो यह आपके आवश्यक चाइल्ड नोड्स के सभी के लिए जाँच करने के लिए एक बेहतर विचार होगा।

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