2012-02-29 16 views
6

साथ प्रकार वस्तु की संपत्ति को क्रमानुसार कैसे मैं एक संपत्ति है। लेकिन जब मैं इस संपत्ति के साथ वस्तु को क्रमबद्ध करता हूं, तो इसे क्रमबद्ध नहीं किया जाता है। क्या संभव प्रकार के साथ XmlSerializer को निर्देश देने का कोई तरीका है?XmlSerializer

+0

मैं तुम्हें ISerializable लागू करने और की क्रमबद्धता को नियंत्रित कर सकता है उम्मीद थी ऑब्जेक्ट को इसके क्रमबद्ध प्रकार में कास्ट करके टैग के प्रकार के आधार पर ऑब्जेक्ट करें। हालांकि मुझे नहीं पता कि आप ऑब्जेक्ट को बाद में कैसे deserialize करेंगे। टाइप ऑब्जेक्ट की चीजों को क्रमबद्ध करने के लिए संभवतः एक अच्छा विचार नहीं है। –

+1

@Adrian 'XmlSerializer' को 'ISerializable' की परवाह नहीं है; हालांकि, मैं इस बात से सहमत हूं कि स्पष्ट रूप से यह परिदृश्य सबसे अच्छा है –

+0

@Marc XmlSerializer को ISERialiable के बारे में परवाह नहीं है, हालांकि यह IXmlSerializable के बारे में परवाह करता है और इसे लागू करने वाले ऑब्जेक्ट पर पढ़ने और लिखने के तरीकों को कॉल करेगा। – Fen

उत्तर

9

मैं इस अनुशंसा नहीं करते हैं, लेकिन हाँ, आप [XmlElement] आदि का उपयोग कर सकते एक सदस्य के लिए कई उम्मीदवार प्रकार के बारे में यह बताने के लिए:

public class Test 
{ 
    private static void Main() 
    { 
     var ser = new XmlSerializer(typeof (Test)); 
     var obj = new Test {Value = "abc"}; 
     ser.Serialize(Console.Out, obj); 
     obj = new Test { Value = 123 }; 
     ser.Serialize(Console.Out, obj); 
     obj = new Test { Value = 456.7F }; 
     ser.Serialize(Console.Out, obj); 
    } 

    [XmlElement("a", Type = typeof(int))] 
    [XmlElement("b", Type = typeof(string))] 
    [XmlElement("c", Type = typeof(float))] 
    public object Value { get; set; } 
} 

उत्पादन के महत्वपूर्ण बिट्स (अनदेखी सभी xmlns/<?xml> आदि) हैं:

<Test> 
    <b>abc</b> 
</Test> 

<Test> 
    <a>123</a> 
</Test> 

<Test> 
    <c>456.7</c> 
</Test> 
+0

पूरी तरह से काम करता है! – user919426

+0

यह केवल तभी काम करता है जब आप तत्वों के लिए अलग-अलग नामों या नामस्थानों का उपयोग करते हैं (हालांकि, इस उदाहरण में ए, बी, सी)। मेरे मामले में, मुझे तत्व नाम की हमेशा आवश्यकता होती है, इसलिए मैंने एक उत्तर पोस्ट किया जो मेरे लिए काम करना प्रतीत होता था। – Evan

0

मैं इसे IXmlSerializable इंटरफेस को लागू करने, एक तत्व विशेषता के रूप में ऑब्जेक्ट प्रकार लेखन किया था।

public void ReadXml(XmlReader reader) 
    { 
    reader.MoveToContent(); 

    Boolean isEmptyElement = reader.IsEmptyElement; 
    reader.ReadStartElement(); 
    if (!isEmptyElement) 
    { 

     // ...here comes all other properties deserialization 

     object tag; 
     if (ReadXmlObjectProperty(reader, "Tag", out tag)) 
     { 
      Tag = tag; 
     } 
     reader.ReadEndElement(); 
    } 
    } 

    public void WriteXml(XmlWriter writer) 
    { 

    // ...here comes all other properties serialization 

    WriteXmlObjectProperty(writer, "Tag", Tag); 
    } 

    public static bool ReadXmlObjectProperty(XmlReader reader, 
              string name, 
              out object value) 
    { 
    value = null; 

    // Moves to the element 
    while (!reader.IsStartElement(name)) 
    { 
     return false; 
    } 
    // Get the serialized type 
    string typeName = reader.GetAttribute("Type"); 

    Boolean isEmptyElement = reader.IsEmptyElement; 
    reader.ReadStartElement(); 
    if (!isEmptyElement) 
    { 
     Type type = Type.GetType(typeName); 

     if (type != null) 
     { 
      // Deserialize it 
      XmlSerializer serializer = new XmlSerializer(type); 
      value = serializer.Deserialize(reader); 
     } 
     else 
     { 
      // Type not found within this namespace: get the raw string! 
      string xmlTypeName = typeName.Substring(typeName.LastIndexOf('.')+1); 
      value = reader.ReadElementString(xmlTypeName); 
     } 
     reader.ReadEndElement(); 
    } 

    return true; 
    } 
    public static void WriteXmlObjectProperty(XmlWriter writer, 
              string name, 
              object value) 
    { 
    if (value != null) 
    { 
     Type valueType = value.GetType(); 
     writer.WriteStartElement(name); 
     writer.WriteAttributeString("Type", valueType.FullName); 
     writer.WriteRaw(ToXmlString(value, valueType)); 
     writer.WriteFullEndElement(); 
    } 
    } 

    public static string ToXmlString(object item, Type type) 
    { 
    XmlWriterSettings settings = new XmlWriterSettings(); 
    settings.Encoding = Encoding.ASCII; 
    settings.Indent = true; 
    settings.OmitXmlDeclaration = true; 
    settings.NamespaceHandling = NamespaceHandling.OmitDuplicates; 

    using(StringWriter textWriter = new StringWriter()) 
    using(XmlWriter xmlWriter = XmlWriter.Create(textWriter, settings)) 
    { 
     XmlSerializer serializer = new XmlSerializer(type); 
     serializer.Serialize(xmlWriter, item, new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty })); 
     return textWriter.ToString(); 
    } 
    } 

नोट: कोड मैं कोई नाम स्थान और ASCII एन्कोडिंग का उपयोग में, उन गैर अनिवार्य विकल्प हैं।

HTH, Cabbi

0

तुम भी वर्ग उस वस्तु प्रॉपर्टी वाला पर [XmlInclude(typeof(YourType))] उपयोग कर सकते हैं। ओपी के मामले में इसलिए, यह इस

[XmlInclude(typeof(PossibleClassOne))] 
[XmlInclude(typeof(PossibleClassTwo))] 
public class MyClass 
{ 
    public object Tag { get; set; } 
} 

इस तरह की तरह लग रहे हैं, तो आप सभी मामलों में अपने तत्व नाम <Tag> रख सकते