El IXmlSerializable
es un poco tedioso para poner en práctica, ya que es más o menos un enfoque de todo o nada teniendo en cuenta que no se puede seleccionar tipos de niños para la serialización XML normal. Sin embargo, si te entendí correctamente, puedes lograr lo que deseas creando manualmente XmlSerializer
para los tipos que no implementan IXmlSerializable
. Por ejemplo, si comenzamos con dos clases, Default
que no implementa IXmlSerializable
y Custom
que sí 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();
}
}
entonces se crea una tercera clase Parent
que tiene un niño de cada uno de los casos anteriores e implementa IXmlSerializable
de una manera que llama ReadXml/WriteXml
métodos para el niño que lo soporta y crear serializador XML por defecto para el otro niño.
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);
}
}
Para hacer el ejemplo completo, un programa de ejemplo que serializa y deserializa un Parent
ejemplo:
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);
}
Thx tanto ... que voy a probar este .. pero parece que en la superficie para ser exactamente lo que necesito. –
Una pequeña nota: Puede usar XmlSerializer para objetos predeterminados y personalizados en los métodos WriteXml()/ReadXml(). – synergetic
Cuando deserializa un objeto secundario entregándole el 'XmlReader', ¿el puntero del lector termina en el lugar correcto (justo al final del elemento hijo) o se retarda? – toddmo