在 C# 中使用派生类从 XML 反序列化对象
Posted
技术标签:
【中文标题】在 C# 中使用派生类从 XML 反序列化对象【英文标题】:Deserializing an object from XML in C# with derived classes 【发布时间】:2020-06-12 08:25:15 【问题描述】:我在下面有一个非常简单的 XML 文件:
<Job Name="test">
<Pages>
<MainPage Name="page1"/>
</Pages>
</Job>
'MainPage'是PageBase的派生类,我的类结构如下
public class Job
[XmlAttribute]
public string Name get; set;
[XmlElement]
public List<PageBase> Pages get; set;
[XmlInclude(typeof(MainPage))]
[XmlInclude(typeof(SubPage))]
public abstract class PageBase
[XmlAttribute]
public string Name get; set;
public class MainPage : PageBase
public class SubPage : PageBase
这是我用来反序列化的示例代码:
var xml = "<Job Name=\"test\"><Pages><MainPage Name=\"page1\"></MainPage></Pages></Job>";
MemoryStream str = new MemoryStream();
StreamWriter writer = new StreamWriter(str);
writer.Write(xml);
writer.Flush();
str.Position = 0;
var serializer = new XmlSerializer(typeof(Job));
var job = (Job)serializer.Deserialize(str);
但是,我收到以下错误 - 尽管在 PageBase 类型中包含了我的 XmlInclude。我究竟做错了什么? DotNetFiddle:https://dotnetfiddle.net/UucVmX
运行时异常(第 18 行):XML 文档中存在错误(1, 19).
堆栈跟踪:
[System.InvalidOperationException:指定的类型是抽象的: name='PageBase', namespace='', at .] at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read4_PageBase(布尔 isNullable, Boolean checkType) 在 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read5_Job(布尔 isNullable, Boolean checkType) 在 Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderJob.Read6_Job()
[System.InvalidOperationException: XML 文档中存在错误 (1, 19).] 在 System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader、字符串 encodingStyle、XmlDeserializationEvents 事件) 在 System.Xml.Serialization.XmlSerializer.Deserialize(Stream 流) 在 Program.Main() :第 18 行
【问题讨论】:
这能回答你的问题吗? XML Serialization and Inherited Types 这个thread 也会有帮助 很遗憾没有,因为我已经有 XmlInclude,但它们不起作用 你应该为抽象类型实现IXmlSerializable
,就像在提到的线程中解释的那样
XmlInclude 的目的不是让这个场景“正常工作”,而不必实现这个接口吗?
在您的类中创建一些测试数据,然后序列化以查看 xml 输出和您的代码生成的内容。 include 需要 type 属性。
【参考方案1】:
将您的 XML 更改为:
<Job Name="test">
<Pages>
<PageBase xsi:type="MainPage" Name="page1"/>
</Pages>
</Job>
首先尝试序列化您的对象并检查它生成的 XML。您应该看到 XML-Element 将是 PageBase 和 xsi:type="MainPage"。
【讨论】:
以上是关于在 C# 中使用派生类从 XML 反序列化对象的主要内容,如果未能解决你的问题,请参考以下文章