Il IXmlSerializable
è un po 'noioso da implementare poiché è praticamente un approccio tutto o niente dato che non è possibile selezionare i tipi di bambino per il normale serializzazione XML. Tuttavia, se ho capito bene, puoi ottenere ciò che desideri creando manualmente XmlSerializer
per i tipi che non implementano IXmlSerializable
.
Ad esempio, se iniziamo con due classi, Default
che non implementa IXmlSerializable
e Custom
che lo implementa.
public class Default // Uses default XML Serialization
{
public int Count { get; set; }
}
public class Custom : IXmlSerializable
{
public int Count { get; set; }
public XmlSchema GetSchema() { throw new NotImplementedException(); }
public void ReadXml(XmlReader reader)
{
reader.ReadToDescendant("Count");
this.Count = reader.ReadElementContentAsInt();
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("Custom");
writer.WriteElementString("Count", this.Count.ToString());
writer.WriteEndElement();
}
}
viene creato una terza classe Parent
che ha un figlio di ciascuno dei casi precedenti e implementa IXmlSerializable
in un modo che richiama ReadXml/WriteXml
metodi per il bambino che lo sostiene e creare serializzatore XML di default per l'altro bambino.
public class Parent : IXmlSerializable
{
public Parent()
{
this.Default = new Default { Count = 1 };
this.Custom = new Custom { Count = 2 };
}
public Default Default { get; set; }
public Custom Custom { get; set; }
public XmlSchema GetSchema() { throw new NotImplementedException(); }
public void ReadXml(XmlReader reader)
{
reader.ReadToFollowing("Custom");
this.Custom = new Custom();
this.Custom.ReadXml(reader);
reader.ReadToFollowing("Default");
var serializer = new XmlSerializer(typeof(Default));
this.Default = (Default)serializer.Deserialize(reader);
}
public void WriteXml(XmlWriter writer)
{
this.Custom.WriteXml(writer);
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
new XmlSerializer(typeof(Default)).Serialize(writer, this.Default, ns);
}
}
Per rendere l'esempio completo, un programma di esempio che serializza e deserializza un'istanza Parent
:
static void Main()
{
var sb = new StringBuilder();
var serializer = new XmlSerializer(typeof(Parent));
serializer.Serialize(new StringWriter(sb), new Parent());
Console.WriteLine(sb);
var parent = (Parent)serializer.Deserialize(new StringReader(sb.ToString()));
Console.WriteLine("Parent.Custom.Count: {0}", parent.Custom.Count);
Console.WriteLine("Parent.Default.Count: {0}", parent.Default.Count);
}
fonte
2010-07-02 17:39:05
Thx tanto ... sto per provare questo .. ma sembra sulla superficie per essere esattamente ciò di cui ho bisogno .. –
Una piccola nota: è possibile utilizzare XmlSerializer sia per gli oggetti Predefinito che per quelli personalizzati nei metodi WriteXml()/ReadXml(). – synergetic
Quando deserializzi un oggetto figlio passandolo a 'XmlReader', il puntatore del lettore finisce nel posto giusto (proprio alla fine dell'elemento figlio), o è ritardato? – toddmo