2012-07-20 20 views
7

Quieres serializar mis datos en este:Cómo XML serializar variedad polimórfica sin envolver elemento

<?xml version="1.0" encoding="ibm850"?> 
<Batch Name="Test batch"> 
    <ExecuteCommand Command="..." /> 
    <WaitCommand Seconds="5" /> 
</Batch> 

Pero en vez estoy recibiendo este (tenga en cuenta la envoltura de comandos del elemento)

<?xml version="1.0" encoding="ibm850"?> 
<Batch Name="Test batch"> 
    <Commands><!-- I want to get rid of thiw wrapper Commands element and just --> 
    <ExecuteCommand Command="..." /> 
    <WaitCommand Seconds="5" /> 
    </Commands> 
</Batch> 

Ésta es la código de muestra utilizado para producir esto:

public class BaseCommand //base class 
{ 
    [XmlAttribute] 
    public string Result { get; set; } 
} 

public class ExecuteCommand : BaseCommand 
{ 
    [XmlAttribute] 
    public string Command { get; set; } 
} 

public class WaitCommand : BaseCommand 
{ 
    [XmlAttribute] 
    public int Seconds { get; set; } 
} 

public class Batch 
{ 
    [XmlAttribute] 
    public string Name { get; set; } 

    private List<BaseCommand> _commands = new List<BaseCommand>(); 
    [XmlArrayItem(typeof(ExecuteCommand))] 
    [XmlArrayItem(typeof(WaitCommand))] 
    public List<BaseCommand> Commands 
    { 
     get 
     { 
      return _commands; 
     } 
     set 
     { 
      _commands = value; 
     } 
    } 

    public static void Main() 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(Batch)); 

     Batch b = new Batch(); 
     b.Name = "Test batch"; 
     b.Commands.Add(new ExecuteCommand() { Command = "..." }); 
     b.Commands.Add(new WaitCommand() { Seconds = 5 }); 

     serializer.Serialize(Console.Out, b); 
     Console.Read(); 
    } 
} 

He buscado y leído un montón de artículos sobre este tema. Todos parecen proporcionar una solución para serializar colecciones con un solo tipo de clase (sin herencia utilizada). Yo uso herencia y nada parece funcionar. Lamentablemente tengo que generar un documento XML preciso debido a la compatibilidad anterior

Respuesta

8

Esto fue hace bastante tiempo, pero finalmente lo descubrí por mi cuenta.

La solución fue añadir [XmlElement] atributo para cada uno de los tipos derivados compatibles con la propiedad de colección

private List<BaseCommand> _commands = new List<BaseCommand>(); 
[XmlElement(typeof(ExecuteCommand))] 
[XmlElement(typeof(WaitCommand))] 
public List<BaseCommand> Commands 
{ 
    get 
    { 
     return _commands; 
    } 
    set 
    { 
     _commands = value; 
    } 
} 
+0

buen hallazgo ...... – GONeale

Cuestiones relacionadas