2011-09-20 12 views
7

को Serializing मैं एक सी # .NET 3.5 आवेदन जहां मैं एक वर्ग एक List<> एक्सएमएल युक्त क्रमानुसार करने करना चाहते हैं। मेरी कक्षा इस तरह दिखता है:एक सूची <> एक ICollection <के रूप में निर्यात> एक्सएमएल

[XmlRoot("Foo")] 
class Foo 
{ 
    private List<Bar> bar_ = new List<Bar>(); 

    private string something_ = "My String"; 

    [XmlElement("Something")] 
    public string Something { get { return something_; } } 

    [XmlElement("Bar")] 
    public ICollection<Bar> Bars 
    { 
     get { return bar_; } 
    } 
} 

तो मैं इसे इस तरह से पॉप्युलेट:

Bar b1 = new Bar(); 
// populate b1 with interesting data 
Bar b2 = new Bar(); 
// populate b2 with interesting data 

Foo f = new Foo(); 
f.Bars.Add(b1); 
f.Bars.Add(b2); 

और फिर इस तरह यह क्रमानुसार:

using (System.IO.TextWriter textWriter = new System.IO.StreamWriter(@"C:\foo.xml")) 
{ 
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Foo)); 
    serializer.Serialize(textWriter, f); 
} 

मैं एक फ़ाइल है कि इस तरह दिखता है मिलती है:

<Foo> 
    <Something>My String</Something> 
</Foo> 

लेकिन, मैं जो चाहता हूं एक्स है एमएल कि इस तरह दिखता है:

<Foo> 
    <Something>My String</Something> 
    <Bar> 
     <!-- Data from first Bar --> 
    </Bar> 
    <Bar> 
     <!-- Data from second Bar --> 
    </Bar> 
</Foo> 

क्या मैं List<> एक्सएमएल में प्रदर्शित करने के पाने के लिए क्या करना होगा?

+0

का उपयोग करें मुझे विश्वास नहीं है कि आप एक इंटरफ़ेस 'XmlSerialize' कर सकते हैं। आप वैसे भी 'ICollection' के रूप में serialize क्यों करना चाहते हैं? 'सूची ' के रूप में क्रमबद्ध करें और उपभोक्ता को वापस 'आईसीओलेक्शन ' ... ??? – IAbstract

+0

@IAbstract - मुझे यकीन नहीं है कि मैं समझता हूं। क्या आप '[XmlElement (" Bar ")] टैग के साथ' निजी सूची बार_' चिह्नित करना चाहते हैं? यह आउटपुट नहीं बदलता है। साथ ही, 'एक्सएमएलएसरियललाइज़र' दस्तावेज से पता चलता है कि यह 'आईन्यूमेरेबल' और 'आईसीओलेक्शन' इंटरफेस दोनों के साथ काम करता है। http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer%28v=VS.90%29.aspx – PaulH

+0

मुझे लगता है कि IAbstract में यह है - आप एक इंटरफ़ेस को क्रमबद्ध नहीं कर सकते हैं। तो इसके बजाय आपको फू को बदलना चाहिए ताकि बार्स एक सूची हो, न कि आईसीओलेक्शन –

उत्तर

2

XmlSerializer की आवश्यकता है कि serializable गुण एक सेटर की है। इसके अलावा, XmlSerializer इंटरफ़ेस गुणों को क्रमबद्ध नहीं कर सकता है। निम्नलिखित कोड काम करेगा:

[XmlElement("Bar")] 
public List<Bar> Bars 
{ 
    get { return bar_; } 
    set { throw new NotSupportedException("This property 'Bars' cannot be set. This property is readonly."); } 
} 

आप इस समाधान पसंद नहीं है (अपवाद थोड़े बदसूरत है) तो आप IXmlSerializable को लागू करने और अपने स्वयं के कस्टम क्रमांकन लिख सकते हैं।

संपादित करें: Artur Mustafin, ठीक है, सदस्यों को बताया कि लागू IEnumerable या ICollectionएक सेटर की आवश्यकता नहीं है के रूप में this msdn page पर समझाया गया है:

XmlSerializer कक्षाएं कि IEnumerable लागू करने के लिए विशेष उपचार देता है या ICollectionIEnumerable लागू करने वाली कक्षा को एक सार्वजनिक पैरामीटर लेने वाले सार्वजनिक Add विधि को लागू करना होगा। जोड़ें विधि का पैरामीटर उसी प्रकार का होना चाहिए जैसा Current से GetEnumerator, या उस प्रकार के बेस से लौटाए गए मान पर वापस लौटाया गया है। के अलावा ICollection (जैसे संग्रहबेस) लागू करने वाली कक्षा में सार्वजनिक Item अनुक्रमित संपत्ति (सी # में इंडेक्सर) होना चाहिए जो एक पूर्णांक लेता है, और इसमें सार्वजनिक पूर्णांक Count प्रकार पूर्णांक होना चाहिए। Add विधि का पैरामीटर उसी प्रकार का होना चाहिए जैसा Item संपत्ति, या उस प्रकार के अड्डों में से एक है। ICollection को लागू करने वाले वर्गों के लिए, अनुक्रमित होने वाले मानों को अनुक्रमित Item संपत्ति से पुनर्प्राप्त किया गया है, न कि GetEnumerator पर कॉल करके।

+2

यह गलत और बदसूरत उत्तर है, यह गलत है क्योंकि यह सेटटर के बिना ईवेंट काम करता है, मेरी पोस्ट –

+0

देखें XmlSerializer को यह आवश्यक नहीं है कि धारावाहिक गुणों में एक बैठानेवाला –

3

सही उत्तर देने के लिए, अपवाद फेंकने के लिए List<T> सार्वजनिक संपत्ति में बदसूरत सेटटर बनाने का कोई मतलब नहीं है।

ऐसा इसलिए है क्योंकि List<> पहले से ही ICollection<T> लागू करता है और हस्ताक्षर शून्य Add(T object) के साथ विधि प्रदान करता है जिसका उपयोग सीरियलाइजेशन तंत्र द्वारा किया जाता है;

आप कर रहे हैं केवल सार्वजनिक गुण धारावाहिक की जा रही करने के लिए सेटर जोड़ने के लिए, और बदलने के लिए ICollection<T>List<T> करने के लिए है:

[XmlRoot("Foo")] 
public class Foo 
{ 
    private List<Bar> bar_ = new List<Bar>(); 

    [XmlElement("Something")] 
    public string Something { get; set; } 

    [XmlElement("Bar")] 
    public List<Bar> Bars { get { return bar_; } } 
} 

आप एक आउटपुट मिल जाएगा:

<?xml version="1.0" encoding="utf-8"?> 
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Something>My String</Something> 
    <Bar /> 
    <Bar /> 
</Foo> 

इसके अलावा, यह एक है परिणाम देखने के लिए, या परीक्षण करने के लिए xml इन-मेमोरी को क्रमबद्ध करने के लिए बेहतर विचार:

static void Main(string[] args) 
{ 
    Bar b1 = new Bar(); 
    // populate b1 with interesting data 
    Bar b2 = new Bar(); 
    // populate b2 with interesting data 

    Foo f = new Foo(); 
    f.Bars.Add(b1); 
    f.Bars.Add(b2); 
    f.Something = "My String"; 

    using (MemoryStream ms = new MemoryStream()) 
    using (System.IO.TextWriter textWriter = new System.IO.StreamWriter(ms)) 
    { 
     System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Foo)); 
     serializer.Serialize(textWriter, f); 
     string text = Encoding.UTF8.GetString(ms.ToArray()); 
     Console.WriteLine(text); 
    } 

    Console.ReadKey(false); 
} 

इंटरफेस का उपयोग करके क्रमबद्ध करने के लिए, मेरी परियोजना XmlSerialization

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