XmlSerializer:保留未知元素

8
我有一个类,可以序列化成XML并存储在文件中,也可以从文件中反序列化并还原:
public class Customer
{
    public string FirstName;
    public string LastName;

    public Customer()
    {
    }

    public Customer(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public static Customer Load(TextReader reader)
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(Customer));
        return (Customer)deserializer.Deserialize(reader);
    }

    public void Save(TextWriter writer)
    {
        XmlSerializer serializer = new XmlSerializer(GetType());
        serializer.Serialize(writer, this);
    }
}

在这个类的较新版本中,我添加了一个新属性。
public string MiddleName;

这是一个常见的用例,即用户安装了我的程序的旧版本和新版本。它们都读写同一个序列化文件。当新版本写入文件时,所有三个属性(FirstNameLastNameMiddleName)都会被写入。旧程序读取文件但省略未知元素 MiddleName。它保存没有 MiddleName 的文件,因此它的值对于较新的程序来说就丢失了。
在反序列化时存储原始 XML,并在序列化时“合并”未知元素,这样旧程序将忽略未知元素,但将其写回文件中,以便新程序不会丢失它们。

2
不是通过xmlserializer,它不知道哪些字段对于它来说是未知的。 - Icepickle
如果在您的数据类上实现IXmlSerializable接口,那么您就可以完全控制序列化过程。我曾经做过非常类似的事情,即在XML反序列化后将原始XML保留为数据实体的一部分,但是将其分配给属性是在反序列化调用之后立即完成的。 - slugster
@slugster 我认为他没有办法更新旧程序的类,因此这是不可能的,但感谢您的更新 :) - Icepickle
@Icepickle 你说得很有道理 :) - slugster
我没有机会更新旧程序,它已经在现场使用了。因此,新程序将使用另一个文件来存储XML。但是为了未来的变更兼容性,新程序将获取XmlAnyElement条目。 - floppes
显示剩余3条评论
2个回答

12

由于我现在使用的是Mac OS X,无法进行测试,但是XmlAnyElement应该可以工作:

[XmlAnyElement]
public XmlElement[] Unsupported { get; set; }

太棒了,这正是我在寻找的! - floppes

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接