2012-10-30 9 views
6

deserializing मैं इस कोड मिल गया है:अज्ञात प्रकार पर ध्यान न दें जब एक्सएमएल

[XmlType("Metadata")] 
[Serializable] 
public class MetadataContainer : List<MetadataBase> 
{ 
} 

[XmlType("Meta")] 
[XmlInclude(typeof(ReadonlyMetadata))] 
[Serializable] 
public abstract class MetadataBase 
{ 
} 

[XmlType("Readonly")] 
[Serializable] 
public class ReadonlyMetadata : MetadataBase 
{ 
} 

[TestFixture] 
public class SerializationTests 
{ 
    [Test] 
    public void Can_deserialize_with_known_type() 
    { 
     const string text = @"<Metadata xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""> 
         <Meta xsi:type=""Readonly"" /> 
        </Metadata>"; 

     var serializer = new XmlSerializer(typeof(MetadataContainer)); 
     var metas = (MetadataContainer)serializer.Deserialize(XmlReader.Create(new StringReader(text))); 

     Assert.That(metas.Count, Is.EqualTo(1)); 
     Assert.That(metas.First(), Is.InstanceOf<ReadonlyMetadata>()); 
    } 

    [Test] 
    public void Can_deserialize_with_unknown_type() 
    { 
     const string text = @"<Metadata xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""> 
         <Meta xsi:type=""Hello"" /> 
        </Metadata>"; 

     var serializer = new XmlSerializer(typeof(MetadataContainer)); 
     var metas = (MetadataContainer)serializer.Deserialize(XmlReader.Create(new StringReader(text))); 

     Assert.That(metas.Count, Is.EqualTo(0)); 
    } 
} 

पहले टेस्ट से काम करता है, लेकिन जब मैं दूसरे को चलाने मैं इस त्रुटि मिलती है: यह हो रही करने के बजाय

System.InvalidOperationException : There is an error in XML document (2, 9). ----> System.InvalidOperationException : The specified type was not recognized: name='Hello', namespace='', at .

त्रुटि मैं इसे मान्यता प्राप्त प्रकारों को अनदेखा करना चाहता हूं। क्या इसे करने का कोई तरीका है? इसी तरह की समस्याओं के लिए

+0

मुझे लगा कि यह (एक या [ 'Unknown'- घटनाओं] इस बारे में की सदस्यता का मामला http://msdn.microsoft.com/en-us/ होगा पुस्तकालय/0a51hxdw.aspx), लेकिन कोशिश करने पर ऐसा लगता है कि यह मदद नहीं करता है। रहस्यमय। – AakashM

+0

मैंने यह भी सोचा कि, परिणाम हालांकि खराब हैं। हालांकि मैं एक समाधान खोजने के लिए प्रबंधन नहीं किया था। – flindeberg

उत्तर

3

जेनेरिक समाधान:

unknown element event (link) और unknown attribute event (link) पर एक नज़र डालें और यदि वे समस्याओं को हल देखते हैं, या हम गंदे हो जाना है। पढ़ें पर ...

मन में इस समस्या को

भालू के लिए कार्य करना समाधान है कि है कि मैं पता नहीं क्या आपके काम है, AFAIK यह आपके आंकड़ा संरचना में एक्सएमएल serializing कर रहा है। यदि आप डेटास्ट्रक्चर को बदल सकते हैं तो मैं आपको Linq2XML पर एक नज़र डालने और अपने उद्देश्यों के लिए एक स्मार्ट फैक्ट्री बनाने की सलाह दूंगा।

[TestMethod] 
public void TestLinq2Xml() 
{ 
    const string text = @"<Metadata xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""> 
          <Meta xsi:type=""Readonly"" /> 
          <Meta xsi:type=""Garbage"" /> 
         </Metadata>"; 

    // Get the "names" of all implementors of MetadataBase 
    var types = AppDomain.CurrentDomain.GetAssemblies().ToList() 
    .SelectMany(s => s.GetTypes()) 
     .Where(p => typeof(MetadataBase).IsAssignableFrom(p) && !p.IsAbstract && !p.IsInterface) 
     .Where(t => t.GetCustomAttributes(typeof(XmlTypeAttribute), false).Any()) 
     .Select(t => t.GetCustomAttributes(typeof(XmlTypeAttribute), false) 
      .Cast<XmlTypeAttribute>().First().TypeName); 

    // Create a parser 
    var parser = new XmlSerializer(typeof(MetadataBase)); 

    // Create metadatacontainer to fill 
    var metas = new MetadataContainer(); 
    // Fill it with matching from from the XML 
    metas.AddRange((from t in XDocument.Parse(text).Descendants("Meta") 
       where types.Contains(t.Attribute(XName.Get("type", "http://www.w3.org/2001/XMLSchema-instance")).Value) 
       select (MetadataBase)parser.Deserialize(t.CreateReader())).ToList()); 

    // Should be one guy present 
    Assert.AreEqual(metas.Count, 1); 
} 
0

किसी सरणी में सभी अज्ञात तत्वों को पकड़ें। आप अभी भी उनके साथ काम कर सकते हैं और बाद में deserialize करने का प्रयास कर सकते हैं, लेकिन यह deserialization को पूरा करने की अनुमति देता है। आपको प्रत्येक वर्ग में इसकी आवश्यकता होगी जिसे आप अपने तत्वों को deserialize करने के लिए परिभाषित करते हैं जहां आपको संदेह है कि अज्ञात तत्व होंगे।

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlanyelementattribute.aspx प्रति:

Public Class XClass 
    ' Apply the XmlAnyElementAttribute to a field returning an array 
    ' of XmlElement objects. 
    <XmlAnyElement()> Public AllElements() As XmlElement 
End Class 'XClass 
+1

डाउनवॉट्स ठीक हैं लेकिन कृपया मेरे उत्तर को संशोधित करने में मेरी सहायता के लिए प्रतिक्रिया छोड़ दें। – VoteCoffee

+0

बहुत ही रोचक जवाब। इसे आजमा देना होगा। – AnthonyVO

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

  • कोई संबंधित समस्या नहीं^_^