2009-04-22 2 views
13

sagen, dass ich ein paar Grundobjekte haben in etwa so:Wie kann ich XML deserialisieren, ohne vorher den Typ zu kennen?

[Serializable] 
public class Base 
{ 

    public string Property1 { get; set; } 
    public int Property2 { get; set; } 
} 

[Serializable] 
public class Sub: Base 
{ 
    public List<string> Property3 { get; set; } 

    public Sub():base() 
    { 
     Property3 = new List<string>(); 
    }   
} 

Und ich serialisiert sie etwa so:

Sub s = new Sub {Property1 = "subtest", Property2 = 1000}; 
s.Property3.Add("item 1"); 
s.Property3.Add("item 2"); 

XmlSerializer sFormater = new XmlSerializer(typeof(Sub)); 
using (FileStream fStream = new FileStream("SubData.xml", 
    FileMode.Create, FileAccess.Write, FileShare.None)) 
{ 
    sFormater.Serialize(fStream, s); 
} 

Wie kann ich deserialisieren ihnen, so dass ich wieder die richtige Klasse bekommen?

Wie in, würde ich so etwas wie diese

XmlSerializer bFormater = new XmlSerializer(typeof (Base)); 
Base newBase; 
using (FileStream fStream = new FileStream("BaseData.xml", 
    FileMode.Open, FileAccess.Read, FileShare.Read)) 
{ 
    newBase = (Base) bFormater.Deserialize(fStream); 
} 

will Außer ich in der Lage sein würde ihm eine XML-Datei für jede Klasse zu übergeben, die erstellt werden würde von Basis und die richtige Klasse absteigt.

Ich denke, ich könnte den Namen des Wurzelknotens des XML lesen und eine switch-Anweisung verwenden, um den richtigen XmlSerializer zu erstellen, aber ich fragte mich, ob es einen einfacheren Weg gab.

+0

Ok. Gerade kontrolliert. Es wirft eine Ausnahme auf. Habe den letzten Para entfernt. – Kirtan

+0

Ok, habe meinen Kommentar gelöscht, da er nicht mehr zutrifft. – Ray

Antwort

8

Verwenden Sie das [XmlInclude] Attribut auf Ihrer Basisklasse die XML-Serializer über abgeleitete Klassen zu erzählen, so dass er herausfinden kann, was zu schaffen. Dein letztes Code-Snippet sollte dann korrekt funktionieren.

+0

Das funktioniert großartig. Vielen Dank. – Ray

+1

Eine zusätzliche Sache, wenn ich die Unterklasse serialisiert habe, muss ich es mit einem XmlSerializer tun, der auf der Basisklasse (nicht der Unterklasse) erzeugt wird. – Ray

+0

[Serializable, XmlInclude (typeof (Sub))] für die Basisklasse –

9

Sie können die XML-Datei der Root-Knoten lesen und stattdessen eine switch-Anweisung zu verwenden, können Sie Ihren Code so schreiben -

Type yourType = Type.GetType("Your Type"); 
XmlSerializer xs = new XmlSerializer(yourType); 

Das glaube ich nicht, dass es eine Möglichkeit, andere als die XML lesen, denn wenn Du kennst den Typ nicht, du kannst nichts tun.

0

Soweit ich weiß, gibt es keinen einfacheren Weg, dies zu tun.

Ich persönlich bevorzuge eine allgemeinere Lösung (wie ich eine Menge verschiedener Klassen in meinem Code serialisiert habe): Typnamen zusammen mit dem Wert serialisiert zu halten.

Sie können für einige weitere Details zu dieser Frage einen Blick: Serialise to XML and include the type of the serialised object