2009-04-22 16 views
13

decir que tengo un par de objetos básicos de este modo:¿Cómo deserializo XML sin conocer el tipo de antemano?

[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>(); 
    }   
} 

Y les serializar este modo:

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); 
} 

cómo puedo deserializar, para que regrese a la clase correcta?

igual que en, me gustaría algo como esto

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); 
} 

Excepto que yo sería capaz de pasar un archivo XML para cualquier clase que desciende desde la base y la clase correcta sería creado.

Estoy pensando que podría leer el nombre del nodo raíz del XML y usar una instrucción switch para crear el XmlSerializer correcto, pero me preguntaba si habría una manera más sencilla.

+0

Ok. Acabo de revisarlo. Está lanzando una excepción. Has eliminado el último párrafo. – Kirtan

+0

Ok, borré mi comentario ya que no se aplica más. – Ray

Respuesta

8

utilizar el atributo [XmlInclude] en su clase base para contar el serializador XML sobre las clases de derivados, por lo que puede averiguar lo que va a crear. Su último fragmento de código debería funcionar correctamente.

+0

Eso funciona genial. Gracias. – Ray

+1

Una cosa adicional, cuando serialicé la subclase, necesito hacerlo con un XmlSerializer creado en la clase Base (no en la clase Sub). – Ray

+0

[Serializable, XmlInclude (typeof (Sub))] en la clase Base –

9

Usted puede leer nodo raíz del archivo XML y en lugar de utilizar una sentencia switch, se puede escribir el código como este -

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

No creo que haya ninguna manera que no sea leer el XML porque si no sabes el tipo, no puedes hacer nada.

0

Por lo que yo sé, no hay una manera más sencilla de hacerlo.

Personalmente prefiero una solución más genérica (ya que tengo que serializar muchas clases diferentes en mi código): mantener el nombre del tipo serializado junto con el valor.

Usted puede echar un vistazo a esta pregunta por algunos detalles: Serialise to XML and include the type of the serialised object

Cuestiones relacionadas