2009-02-09 10 views
6

का उपयोग कर व्युत्पन्न वर्ग को क्रमबद्ध करना मेरे पास एक बेस क्लास है जो एक्सएमएल सीरियलाइजेशन और एक व्युत्पन्न कक्षा के साथ संगत है जो IXmlSerializable लागू करता है।सी # एक्सएमएल- IXmlSerializable

इस उदाहरण में, आधार वर्ग IXmlSerializable को लागू करता है:


using System.Diagnostics; 
using System.Text; 
using System.Xml; 
using System.Xml.Schema; 
using System.Xml.Serialization; 

namespace XmlSerializationDerived 
{ 
    public class Foo 
    { 
     public int fooProp; 

     public XmlSchema GetSchema() 
     { 
      return null; 
     } 

     public void ReadXml(XmlReader reader) 
     { 
      fooProp = int.Parse (reader.ReadElementString ("fooProp")); 
     } 

     public void WriteXml(XmlWriter writer) 
     { 
      writer.WriteElementString ("fooProp", fooProp.ToString()); 
     } 
    } 

    public class Bar : Foo, IXmlSerializable 
    { 
     public new void ReadXml(XmlReader reader) 
     { 
      base.ReadXml (reader); 
     } 

     public new void WriteXml(XmlWriter writer) 
     { 
      base.WriteXml (writer); 
     } 

     static void Main(string[] args) 
     { 
      StringBuilder sb = new StringBuilder(); 
      XmlWriter writer = XmlWriter.Create (sb); 

      Bar bar = new Bar(); 
      bar.fooProp = 42; 

      XmlSerializer serializer = new XmlSerializer (typeof (Bar)); 
      serializer.Serialize (writer, bar); 

      Debug.WriteLine (sb.ToString()); 
     } 
    } 
} 

यह इस उत्पादन का उत्पादन:

<?xml version="1.0" encoding="utf-16"?><Bar><fooProp>42</fooProp></Bar> 

हालांकि, मैं एक आधार वर्ग जो नहीं करता है का उपयोग करना चाहते IXmlSerializable लागू करें। यह base.Read/WriteXml का उपयोग रोकता है। नतीजा होगा:

<?xml version="1.0" encoding="utf-16"?><Bar /> 

क्या वांछित परिणाम प्राप्त करने का कोई तरीका है?

उत्तर

2

"यह आधार का उपयोग करने से रोकता है। रीड /WriteXml।"

आमतौर पर, यदि बेस-क्लास IXmlSerializable लागू किया गया है, तो आप इसे virtual विधि बना सकते हैं ताकि कंक्रीट संस्करण का उपयोग किया जा सके। आम तौर पर, आप कार्यान्वयन विवरण के लिए कुछ protected virtual विधियों के साथ स्पष्ट कार्यान्वयन (सार्वजनिक गुणों के बजाय) का उपयोग भी करेंगे (हालांकि पाठक/लेखक विभिन्न वर्गों में कहां है, इसका ट्रैक रखना) एक दुःस्वप्न होगा।

AFAIK, वहाँ कोई रास्ता नहीं है फिर से उपयोग करने के लिए XmlSerializer, आधार बिट्स लिखने के लिए आप जोड़ना जबकि व्युत्पन्न बिट्स है। IXmlSerializable सब कुछ या कुछ भी नहीं है।

+0

जावा से आ रहा है और यह मृत आसान क्रमबद्धता है, मैं इसे सुनकर थोड़ा दुखी हूं। मैंने वास्तव में बेस क्लास बनाया, जिसे मैं सौभाग्य से एक्सेस करता हूं, IXmlSerializable को लागू करता हूं। यह काम करता है, लेकिन यह दर्द होता है, क्योंकि मैं कोड लिख रहा हूं जो अस्तित्व में नहीं है। – mafu

+0

जब तक कोई नया दृष्टिकोण नहीं लेता है, यह आधिकारिक उत्तर है। – mafu

1

क्यों न केवल अपने पढ़ने/लिखने के फ़ंक्शन में XmlSerializer का उपयोग करें?

XmlSerializer s = new XmlSerializer(typeof(Foo)); 
s.Serialize(writer, base); 
+1

क्योंकि इसे कारणों से मैन्युअल रूप से क्रमबद्ध किया जाना था, अब मुझे याद नहीं किया जा सकता है। :) – mafu

4

mtlung के उत्तर में सुधार, आप XmlSerializer का उपयोग क्यों नहीं करते? आप अपनी कक्षा को विशेषता के साथ ट्यून कर सकते हैं ताकि इसे जिस तरह से आप चाहते हैं उसे क्रमबद्ध किया जा सके, और यह करना बहुत आसान है।

using System.Xml.Serialization; 

... 

[XmlRoot("someclass")] 
public class SomeClass 
{ 
    [XmlAttribute("p01")] 
    public int MyProperty01 
    { 
     get { ... } 
    } 

    [XmlArray("sometypes")] 
    public SomeType[] MyProperty02 
    { 
     get { ... } 
    } 

    [XmlText] 
    public int MyProperty03 
    { 
     get { ... } 
    } 

    public SomeClass() 
    { 
    } 
} 

फिर, serializing और यह deserializing बहुत सरल होगा:

void Save(SomeClass obj) 
{ 
    XmlSerializer xs = new XmlSerializer(typeof(SomeClass)); 
    using (FileStream fs = new FileStream("c:\\test.xml", ...)) 
    { 
     xs.Serialize(fs, obj); 
    } 
} 

void Load(out SomeClass obj) 
{ 
    XmlSerializer xs = new XmlSerializer(typeof(SomeClass)); 
    using (FileStream fs = new FileStream("c:\\test.xml", ...)) 
    { 
     obj = xs.Deserialize(fs); 
    } 
} 

और जिसके परिणामस्वरूप एक्सएमएल कुछ इस तरह होगा:

<someclass p01="..."> 
    <sometype> 
    <!-- SomeType serialized objects as child elements --> 
    </sometype> 
    # value of "MyProperty03" as text # 
</someclass> 

इस विधि "POCO" के साथ बेहतर काम करता है कक्षाएं, और यह सरल और साफ है। आपको विशेषताओं का उपयोग करने की भी आवश्यकता नहीं है, वे क्रमबद्धता को अनुकूलित करने में आपकी सहायता के लिए हैं।

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