如何将遗留XML序列化类类型反序列化为新类类型?
问题
我维护一个内部遗留API,该API使用两个通过XML序列化的类,二者均继承自同一个基类:
namespace My.Namespace { [ Serializable, XmlInclude(typeof(SubClassA)), XmlInclude(typeof(SubClassB)), ] public abstract class BaseClass { // etc. } [ Serializable, XmlType(TypeName="My.Namespace.SubClassA"), ] public sealed class SubClassA: BaseClass { // etc. } [ Serializable, XmlType(TypeName="My.Namespace.SubClassB"), ] public sealed class SubClassB: BaseClass { // etc. } }
目前这两个子类已重构为单个新类SubClass(二者差异极小),同样继承自BaseClass。现在需要让新类能够反序列化定义了SubClassA和SubClassB实例的遗留XML文件,但这两个旧类已从API中移除无法使用。如何配置BaseClass和SubClass,使新序列化的XML文件定义SubClass实例,同时能将遗留XML中的SubClassA、SubClassB实例反序列化为SubClass实例?能否在反序列化XML时将SubClassA和SubClassB设为SubClass的别名?(假设三者序列化属性一致)
解决方案
可以通过XmlAttributeOverrides结合特性配置实现需求,既支持新类的正常序列化,又能兼容旧XML的反序列化,具体步骤如下:
1. 调整基类BaseClass的特性
移除对已删除的SubClassA、SubClassB的XmlInclude引用,只保留新类SubClass的引用:
namespace My.Namespace { [Serializable] [XmlInclude(typeof(SubClass))] public abstract class BaseClass { // 原有业务逻辑 } }
2. 配置新类SubClass的默认序列化名称
给SubClass添加XmlType特性,指定新序列化时使用的类型名称:
namespace My.Namespace { [Serializable] [XmlType(TypeName = "My.Namespace.SubClass")] public sealed class SubClass : BaseClass { // 原有合并后的逻辑 } }
3. 用XmlAttributeOverrides实现旧类型到新类的映射
在创建XmlSerializer实例时,通过XmlAttributeOverrides将旧的SubClassA、SubClassB类型名称映射到SubClass,这样反序列化时就能识别旧XML中的类型并转换为新类实例:
// 初始化配置实例 var overrides = new XmlAttributeOverrides(); // 为基类添加旧类型到新类的映射 var baseAttrs = new XmlAttributes(); // 映射旧类型SubClassA到SubClass baseAttrs.XmlElements.Add(new XmlElementAttribute("My.Namespace.SubClassA", typeof(SubClass))); // 映射旧类型SubClassB到SubClass baseAttrs.XmlElements.Add(new XmlElementAttribute("My.Namespace.SubClassB", typeof(SubClass))); overrides.Add(typeof(BaseClass), baseAttrs); // 创建兼容新旧XML的序列化器 var serializer = new XmlSerializer(typeof(BaseClass), overrides);
效果验证
- 新XML序列化:生成的XML会使用
SubClass指定的类型名称My.Namespace.SubClass; - 旧XML反序列化:遗留XML中标记为
SubClassA或SubClassB的实例,会被自动反序列化为SubClass的实例,因为我们已将这两个旧类型名称映射到新类。
注意:由于题目假设三者序列化属性完全一致,因此无需额外配置字段/属性的映射,上述方案可直接生效。
内容的提问来源于stack exchange,提问作者FunctionalFolds
相关产品推荐
相关产品推荐

