如果使用自定义XML序列化(IXmlSerialiable
),则在包含具有组成复杂对象的属性的复杂对象上,这些对象具有而不是使用自定义IXmlSerializable
接口(interface),如何在IXmlSerializable.ReadXml(XmlReader reader)
方法中指定要反序列化器使用普通反序列化在那些 child 的属性(property)?
注意:类似于this question
最佳答案
IXmlSerializable
的实现有点繁琐,因为考虑到您不能为常规XML序列化选择子类型,这几乎是一种全有或全无的方法。但是,如果我对您的理解正确,则可以通过为未实现XmlSerializer
的类型手动创建IXmlSerializable
来实现所需的功能。
例如,如果我们从两个类开始,则不实现Default
的IXmlSerializable
和实现它的Custom
。
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();
}
}
然后,我们创建第三个类
Parent
,该类具有每个先前实例的子级,并以对支持该子级的子级调用IXmlSerializable
方法并为另一个子级创建默认XML序列化器的方式实现ReadXml/WriteXml
。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);
}
}
为了使示例更完整,示例程序对
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);
}
关于.net - 在复杂对象图上使用IXmlSerializable接口(interface),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3167067/