【问题标题】:XML Deserialization of Inherited Objects继承对象的 XML 反序列化
【发布时间】:2009-10-25 04:26:48
【问题描述】:

我有一个对象InputFile,它有数组和对象来保存文件的内容。我还有ABCFileXYZFile,它们都继承自InputFile,它们将读取不同类型的文件并将它们存储到InputFile 的投影成员中。

由于这两个对象的序列化和反序列化与父对象相同,所以我在父对象上实现了标准的XML序列化接口。在反序列化过程中读取一些参数,调用Read 函数(以加载文件),然后反序列化完成。

序列化效果很好,但反序列化(List<InputFile>)不起作用,因为反序列化程序调用父存根文件函数Read,而不是ABCFileXYZFile

如何让反序列化识别要使用的正确类型的对象?我的List<InputFile> 可能会有多种文件类型。

谢谢

我用来序列化对象的代码:

public class InputFileHolder : IXmlSerializable {
...
public void WriteXml(XmlWriter w) {
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("", "");

    XmlSerializer ifXml = new XmlSerializer(typeof(List<InputFile>));
    ifXml.Serialize(w, InputFiles, ns);

    //More serialization
}

在我自定义序列化列表时如何维护对象类型有什么想法吗?

【问题讨论】:

    标签: c# xml inheritance serialization


    【解决方案1】:

    试试

    [XmlArray]
    [XmlArrayItem(ElementName="ABCFile", Type=typeof(ABCFile))]
    [XmlArrayItem(ElementName="XYZFile", Type=typeof(XYZFile))]
    public List<InputFile> InputFileList
    {
       get;
       set;
    }
    

    这将指示序列化程序,即使这是一个 InputFile 列表,也会有两个派生类型将存储在此列表中。它可能会使其对每个方法使用特定版本的方法。

    如果失败,请告诉我。

    根据您的评论进行修改

    我不明白这是怎么回事。

    我测试了以下类:

    public class InputFile
    {
        public String InputfileCommonProperty { get; set; }
    }
    
    public class ABCFile : InputFile
    {
        public String ABCSpecificProperty { get; set; }
    }
    
    public class XYZFile : InputFile
    {
        public String XYZSpecificProperty { get; set; }
    }
    
    public class InputFileHolder
    {
        public InputFileHolder()
        {
            InputFileList = new List<InputFile>();
        }
    
        [XmlArray]
        [XmlArrayItem(ElementName = "ABCFile", Type = typeof(ABCFile))]
        [XmlArrayItem(ElementName = "XYZFile", Type = typeof(XYZFile))]
        public List<InputFile> InputFileList { get; set; }
    }
    

    我的主程序如下所示:

    static void Main(string[] args)
    {
        InputFileHolder fileHolder = new InputFileHolder();
        fileHolder.InputFileList.Add(
            new ABCFile()
            {
                InputfileCommonProperty = "This is a common property",
                ABCSpecificProperty = "This is a class specific property"
            });
    
        XmlSerializer serializer = new XmlSerializer(typeof(InputFileHolder));
        MemoryStream memoryStream = new MemoryStream();
        serializer.Serialize(memoryStream, fileHolder);
    
        System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
        String serializedString = enc.GetString(memoryStream.ToArray());
    }
    

    最后,serializedString的内容是:

    <?xml version="1.0"?>
    <InputFileHolder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <InputFileList>
        <ABCFile>
          <InputfileCommonProperty>This is a common property</InputfileCommonProperty>
          <ABCSpecificProperty>This is a class specific property</ABCSpecificProperty>
        </ABCFile>
      </InputFileList>
    </InputFileHolder>
    

    你看到了吗?序列化程序知道它是 ABCFile 而不是通用 InputFile。

    【讨论】:

    • 感谢您的快速回复。生成的 XML 仍然看起来像:。如果我手动编辑 XML 以将 InputFile 更改为 ABCFile 它会失败并出现错误的 XML 错误。
    • 好的,它认为我已经找到了问题的根源。我的 InputFileHolder 版本有一个 IXmlSerializable 接口,我可以在其中自定义读/写参数以进行序列化。如果我删除 IXmlSerializable 接口并让框架处理它,我会得到像你一样的 XML,其中指定了对象类型。我需要自定义读取,所以我需要修复写入。我将在主帖中添加我的编写代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    相关资源
    最近更新 更多