2009-04-27 10 views
12
<?xml version="1.0" encoding="utf-8" ?> 
<pages> 
    <page id="56"> 
    <img id="teaser" src="img/teaser_company.png"></img> 
    </page> 
</pages> 

मेरे पास एक XML फ़ाइल है जो एक सीएमएस के भीतर पृष्ठों के लिए अतिरिक्त संसाधनों को परिभाषित करती है। LinqToXml के साथ इस फ़ाइल को पूछते समय नल संदर्भ अपवादों की रक्षा करने का सबसे अच्छा तरीका क्या है?लिंक टू एक्सएमएल में आप नल रेफरेंस अपवादों की रक्षा कैसे करते हैं?

var page = (from tabElement in extensionsDoc.Descendants("page") 
where tabElement.Attribute("id").Value == tabId.ToString() 
select tabElement).SingleOrDefault(); 

यदि कोई पृष्ठ तत्व "आईडी" नामक विशेषता नहीं है तो यह कोड संभावित रूप से शून्य संदर्भ अपवाद को ट्रिगर कर सकता है। क्या मुझे एक कोशिश पकड़ ब्लॉक का उपयोग करना है या इसे संभालने का कोई तरीका है? उदाहरण के लिए पृष्ठ तत्व के लिए "id" नामक कोई विशेषता नहीं है, तो पेज ऑब्जेक्ट पृष्ठ के लिए शून्य वापस करें।

+0

कैसे tabId अग्रिम की जाँच के बारे में? –

उत्तर

28

संपादित करें: यह स्पष्ट रूप से बहुत समय पहले लिखा गया था - इन दिनों मैं निश्चित रूप से इगोर के उत्तर के अनुसार कलाकारों के साथ जाऊंगा। कुछ

सबसे आसान तरीका होगा की तरह:

var page = (from tabElement in extensionsDoc.Descendants("page") 
      let idAttribute = tabElement.Attribute("id") 
      where idAttribute != null 
        && idAttribute.Value == tabId.ToString() 
      select tabElement).SingleOrDefault(); 

वैकल्पिक रूप से आप XElement के लिए एक विस्तार विधि लिख सकते हैं:

public static string AttributeValueOrDefault(this XElement element, 
              string attributeName) 
{ 
    XAttribute attr = element.Attribute(attributeName); 
    return attr == null ? null : attr.Value; 
} 

तो का उपयोग करें:

var page = (from element in extensionsDoc.Descendants("page") 
      where element.AttributeValueOrDefault("id") == tabId.ToString() 
      select element).SingleOrDefault(); 

या डॉट उपयोग करने के लिए नोटेशन:

var page = extensionsDoc.Descendants("page") 
      .Where(x => x.AttributeValueOrDefault("id") == tabId.ToString()) 
      .SingleOrDefault(); 

(यह भावना tabId.ToString() कॉल करने के लिए एक बार पहले से, btw, बल्कि हर यात्रा के लिए की तुलना में होगा।)

+0

एक्सटेंशन विधि केवल तभी काम करेगी जब आपको इसकी लंबाई की तरह विशेषता की संपत्ति की आवश्यकता न हो। 'x.AttributeValueOrDefault (" id ")। उदाहरण के लिए लंबाई> 0' अभी भी एक NullReferenceException फेंक देगा। मुझे लगता है कि 'लेट' का उपयोग सुरक्षित है। _BTW, दुर्भाग्यवश ReSharper संभावित NullReferenceEception के बारे में चेतावनी नहीं देता है अगर आप _ 'let' _ का उपयोग करते हैं और _ _ null' की जांच नहीं करते हैं। – comecme

+0

@comecme: उस स्थिति में आप नल-कोलेसिंग ऑपरेटर का उपयोग कर सकते हैं। यह एक पैनसिया नहीं था ... हालांकि स्पष्ट कलाकार का उपयोग करना वास्तव में बेहतर होगा। –

3

मैंने देखा है अन्य लोगों के साथ-साथ पहले एक स्ट्रिंग के लिए एक सीधी डाली का उपयोग करें; मुझे नहीं पता कि जॉन ने जो सुझाव दिया है उससे कहीं अधिक कम या कम कुशल है, लेकिन मुझे वाक्यविन्यास पसंद है।

var page = extensionsDoc.Descendants("page") 
      .Where(x => (string)x.Attribute("id") == tabId.ToString()) 
      .SingleOrDefault(); 

कोई भी यह सोचने के लिए स्वतंत्र महसूस करता है कि मेरी सोच में कुछ दोष है; मैं LINQ के लिए काफी नया हूँ।

1

मैं XPath अभिव्यक्तियों का उपयोग करता हूं जहां कोड अन्यथा शून्य जांच के साथ अव्यवस्थित हो जाएगा। आपके उदाहरण के लिए:

var query = string.Format("page[@id='{0}']", tabId.ToString()); 
var page = extensionsDoc.XPathSelectElement(query); 
10

.NET में XML करने के लिए 4 LINQ करने के लिए एक तरीका प्रदान करता है और यह explicit casts का उपयोग कर के माध्यम से है:

var page = (
    from tabElement in extensionsDoc.Descendants("page") 
    where (string)tabElement.Attribute("id") == tabId.ToString() 
    select tabElement 
).SingleOrDefault(); 

तो विशेषता वहाँ नहीं तो परिणाम बस होगा है, शून्य हो

स्पष्ट string ऑपरेटर के अलावा, यहां तक ​​कि प्राचीन प्रकार के अधिकांश और उनके नालीबल संस्करण भी हैं। इसका मतलब यह है कि आप AttributeOrDefault वाक्य रचना इस तरह का उपयोग कर सकते हैं:

//<element theAttr="12" /> 
int theAttr = (int?)doc.Element("element").Attribute("missingAttr") ?? 0; 
+2

यदि आपका कोई तत्व 'तत्व "मौजूद नहीं है तो आपका अंतिम उदाहरण NullReferenceException का मामला हो सकता है। – comecme

0

मैं XML तत्व मानचित्रण एक वर्ग इकाई का प्रयोग करेंगे। और एक विधि को कॉल करें जो शून्य मान की जांच करेगा। मैं अपने कोड में इस विधि का उपयोग करता हूं, यह ठीक काम करता है। आशा करता हूँ की ये काम करेगा।

यहाँ अपनी आवश्यकताओं पर निर्भर करता है समायोजित करने के लिए एक नमूना कोड है:

private void Method1(...) { 
    ... 

    var pages = from tabElement in extensionsDoc.Descendants("page") 
    where tabElement.Attribute("id").Value == tabId.ToString() 
    select new Page { 
       imgSrc = Method2(tabElement) 
      }; 

    // pages variable is a List<Page> object 
    ... 
} 

private void Method2(XElement element) { 
    XElement img = element.Element("img"); 

    if (img != null) { 
     ... 
     // TODO return the imgSrc 
     return ""; 
    } 

    // return null or "" 
    return null; 
} 

फिर पृष्ठ वर्ग परिभाषा:

class Page 
{ 
    public string imgSrc { get; set; } 
} 
+0

यदि 'tabElement' में कोई विशेषता आईडी नहीं है, तो यह अभी भी आपके 'विधि 1' में NullReferenceException का कारण बन जाएगा। – comecme

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