2012-03-12 14 views
6

निम्न XML पर विचार करें। तो, मैंने निम्नलिखित कक्षा लिखी।खाली तत्वों के साथ deserialize Xml

public class A 
{ 
    [XmlElement("b", Namespace = "")] 
    public int? B { get; set; } 

    [XmlElement("c", Namespace = "")] 
    public int? C { get; set; } 

} 

के बाद से मैं nullables उपयोग कर रहा हूँ, मैं उम्मीद कर रहा था कि, जब ऊपर एक्सएमएल deserialing, मैं एक अशक्त सी संपत्ति के साथ एक वस्तु एक मिलेगा।

इसके बजाय, मुझे एक अपवाद मिलता है कि दस्तावेज़ में कोई त्रुटि है।

+0

* नहीं:

foo.b = 2; foo.c = 0; //for example, if it's an integer 

मैं इस लिंक से जानकारी शामिल हो गए। यह शून्य-लंबाई वाली स्ट्रिंग है। –

+0

कृपया अपने शीर्षक "सी #" के साथ उपसर्ग न करें। टैग के लिए यही है। –

उत्तर

7

तत्व और शून्य तत्व के बीच एक अंतर है।

एक गायब तत्व, <a><b>2</b></a>। यहां सी डिफ़ॉल्ट वैल्यू विशेषता का उपयोग करके निर्दिष्ट डिफ़ॉल्ट मान लेगा, या कोई स्पष्ट डिफ़ॉल्ट नहीं होने पर शून्य हो जाएगा।

एक शून्य तत्व <a><b>2</b><c xs:Nil='true'/></a>। यहाँ आप शून्य हो जाएगा।

जब आप <a><b>2</b><c></c><a/> करते हैं तो xml serializer स्ट्रिंग को पार्स करने का प्रयास करेगा। एक पूर्णांक के रूप में लक्षण सही ढंग से विफल हो जाएगा।

के बाद से अपने प्रदाता अवैध एक्सएमएल पैदा कर रहा है आप अगर XmlSerializer का उपयोग कर, यह करने के लिए की आवश्यकता होगी:

[XmlRoot(ElementName = "a")] 
public class A 
{ 
    [XmlElement(ElementName = "b")] 
    public int? B { get; set; } 

    [XmlElement(ElementName = "c")] 
    public string _c { get; set; } 

    public int? C 
    { 
     get 
     { 
      int retval; 

      return !string.IsNullOrWhiteSpace(_c) && int.TryParse(_c, out retval) ? (int?) retval : null; 
     } 
    } 
} 

या थोड़ा बेहतर का उपयोग कर DataContractSerializer

[DataContract(Name="a")] 
public class A1 
{ 
    [DataMember(Name = "b")] 
    public int? B { get; set; } 

    [DataMember(Name = "c")] 
    private string _c { get; set; } 

    public int? C 
    { 
     get 
     { 
      int retval; 

      return !string.IsNullOrWhiteSpace(_c) && int.TryParse(_c, out retval) ? (int?)retval : null; 
     } 
    } 
} 

हालांकि DataContractSerializer का समर्थन नहीं करता विशेषताएं अगर यह एक समस्या है।

+0

आपकी पोस्ट के लिए धन्यवाद। मुझे पता है कि तुम मुझे क्या बता रहे हो। लेकिन मेरे पास एक्सएमएल डेटा का नियंत्रण नहीं है (यह बाहरी सेवा से आ रहा है)। और सेविस प्रदाता लौट रहे हैं, वास्तव में इसे एक एक्सएस: एनआईएल = 'सच' वापस करना चाहिए, इसलिए मुझे इससे निपटना होगा। –

+0

आपको सी को एक स्ट्रिंग बनाना होगा और उसके बाद एक रैपर प्रॉपर्टी होगी जो deserialized स्ट्रिंग को int में पार्स करेगी? जैसी ज़रूरत। – Phil

+0

धन्यवाद। "IsNullOrWhiteSpace" के बजाय आपका परीक्षण "Strng.IsNullOrEmpty" नहीं होना चाहिए? आपको कास्ट (int?) प्रतिशोध करने की आवश्यकता नहीं है। हालांकि, संकलन त्रुटियों से बचने के लिए, हमें (int?) Null –

1

अपने उदाहरण की तरह 'सी' रिक्त टैग्स deserialize करने के लिए:

<foo> 
     <b>2</b> 
     <c></c> 
    </foo> 

मैं इस दृष्टिकोण का इस्तेमाल किया। सबसे पहले यह LINQ का उपयोग कर एक्सएमएल फ़ाइल से शून्य या खाली तत्वों को हटा देता है और फिर यह नए दस्तावेज़ को फू क्लास में शून्य या खाली टैग के बिना deserialize।

public static Foo ReadXML(string file) 
    { 
      Foo foo = null; 
      XDocument xdoc = XDocument.Load(file); 
      xdoc.Descendants().Where(e => string.IsNullOrEmpty(e.Value)).Remove(); 

      XmlSerializer xmlSer = new XmlSerializer(typeof(Foo)); 
      using (var reader = xdoc.Root.CreateReader()) 
      { 
       foo = (Foo)xmlSer.Deserialize(reader); 
       reader.Close(); 
      } 
      if (foo == null) 
       foo = new Foo(); 

      return foo; 
    } 

जो आपको अनुपलब्ध गुणों पर डिफ़ॉल्ट मान देगा। * अशक्त

Remove empty XML tags

Use XDocument as the source for XmlSerializer.Deserialize?

+0

क्यों नहीं 'xdoc.Descendants()। जहां (e => e.IsEmpty || String.IsNullOrWhiteSpace (e.Value)) '? – stomy

+0

आप 'टेक्स्ट (रीडर रीडर रीडर = नया स्ट्रिंग रीडर (xdoc.ToString()) का उपयोग करके भी कर सकते हैं। – stomy

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