2011-11-22 1 views
9

Ho bisogno di serializzare IEnumerable. Allo stesso tempo voglio che il nodo root sia "Canali" e il nodo di secondo livello - Canale (invece di ChannelConfiguration).Ignora nome classe per XmlSerialization

Ecco la mia definizione serializzatore:

_xmlSerializer = new XmlSerializer(typeof(List<ChannelConfiguration>), new XmlRootAttribute("Channels")); 

ho sovrascritto nodo principale, fornendo XmlRootAttribute ma non ho trovato un'opzione per impostare canale invece di ChannelConfiguration come secondo nodo di livello.

So che posso farlo introducendo un wrapper per IEnumerable e utilizzando XmlArrayItem ma non voglio farlo.

+3

perché non si vuole fare la scelta più facile? per curiosità? (si noti anche che l'uso di costruttori non banali significa ** deve ** memorizzare il serializzatore, altrimenti si perde l'assembly, il costruttore base 'XmlSerializer (Type)' non ne risente) –

+0

Sei il proprietario della classe ChannelConfiguration, sono sei in grado di decorarlo con attributi? Se sì, ho probabilmente una soluzione. –

+0

@MarcGravell, potresti aver ragione e dovrei usare un wrapper – SiberianGuy

risposta

15

Come così:

XmlAttributeOverrides or = new XmlAttributeOverrides(); 
or.Add(typeof(ChannelConfiguration), new XmlAttributes 
{ 
    XmlType = new XmlTypeAttribute("Channel") 
}); 
var xmlSerializer = new XmlSerializer(typeof(List<ChannelConfiguration>), or, 
    Type.EmptyTypes, new XmlRootAttribute("Channels"), ""); 
xmlSerializer.Serialize(Console.Out, 
    new List<ChannelConfiguration> { new ChannelConfiguration { } }); 

Nota si must cache e riutilizzo questa istanza serializzatore.

Devo anche dire che raccomando vivamente di utilizzare l'approccio "classe wrapper" - più semplice, nessun rischio di perdita di assemblaggio, e IIRC funziona su più piattaforme (sono sicuro di aver visto un caso limite dove sopra si comporta diversamente su alcune implementazioni - SL o WP7 o qualcosa del genere).

Se si ha accesso al tipo di ChannelConfiguration, si può anche semplicemente usare:

[XmlType("Channel")] 
public class ChannelConfiguration 
{...} 

var xmlSerializer = new XmlSerializer(typeof(List<ChannelConfiguration>), 
    new XmlRootAttribute("Channels")); 
xmlSerializer.Serialize(Console.Out, 
    new List<ChannelConfiguration> { new ChannelConfiguration { } }); 
11

Questo dovrebbe fare il trucco, se non ricordo male.

[XmlType("Channel")] 
public class ChannelConfiguration { 

} 
+1

Funziona solo se possiedi la classe e puoi decorarla. –

+0

No, non :(XmlElement non può essere applicato a una classe – SiberianGuy

+0

Penso che intendessi XmlRoot ("Canale")? –