Personalizzare l'XML prodotto dalla serializzazione di una classe con XmlSerialization è motlo semplice; è sufficiente infatti far implementare alle classi coinvolte nella serializzazione l'interfaccia IXmlSerializer.
Voglio mostrarvi un esempio: ho avuto la necessità di serializzare una classe che conteneva alcune liste di altre classi; il documento prodotto non doveva raggruppare le varie liste in nodi che rappresentavano le proprietà, ma elencare tutte le istanze sotto il nodo radice.
La classi di esempio:
public class InterfaceIn : IXmlSerializable
{
public List<Field> Fields { get; set; }
public List<Constant> Constants { get; set; }
...
}
XML che dovrebbe essere prodotto:
<INTERFACEIN>
<CONSTANT DESTINATION="COMMIT_FLAG" VALUE="X" />
<CONSTANT DESTINATION="SAVE_FLAG" VALUE="X" />
<FIELD NAME="DOC_NUMBER" DESTINATION="DOKNR" />
<FIELD NAME="DOC_PART" DESTINATION="DOKTL" />
</INTERFACEIN>
E uno stralcio di implementazione dell'interfaccia IXmlSerailizable delle classi coinvolte:
Esempio di deserializzazione di InterfaceIn
public void ReadXml(System.Xml.XmlReader reader)
{
reader.Read();
while (!reader.EOF)
{
if (reader.IsStartElement())
{
switch (reader.Name)
{
case "FIELD":
var f = new Field();
f.ReadXml(reader);
this.Fields.Add(f);
break;
case "CONSTANT":
var c = new Constant();
c.ReadXml(reader);
this.Constants.Add(c);
break;
}
}
reader.Read();
}
}
Esempio di serializzazione di InterfaceIn
public void WriteXml(System.Xml.XmlWriter writer)
{
foreach (var f in this.Fields)
f.WriteXml(writer);
foreach (var c in this.Costants)
c.WriteXml(writer);
}
Esempio di serializzazione di Field:
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteStartElement("FIELD");
writer.WriteAttributeString("NAME", this.Name);
writer.WriteAttributeString("DESTINATION", this.Destination);
writer.WriteEndElement();
}
In buona sostanza è sufficiente avere un po' di dimistischezza con l'uso degli Stream, per ottenere delle serializzazioni personalizzate.
Matteo