当元素可能是许多可能元素之一时,将 XML 元素反序列化为对象

Posted

技术标签:

【中文标题】当元素可能是许多可能元素之一时,将 XML 元素反序列化为对象【英文标题】:Deserializing XML element to an Object when the element could be one of many possible elements 【发布时间】:2011-06-15 11:55:41 【问题描述】:

在通过 pub/sub 以 XML 格式传输消息的本地框架中,我需要能够使用许多消息,但是,所有消息都作为简单文本接收,并且必须反序列化为由 Xsd 工具创建的对象。

消息本身都是从基本 MessageType 元素/对象派生的,但如果我基于这样的反序列化:

XmlSerializer 序列化器 = new XmlSerializer(typeof(MessageType));
XmlReader 阅读器 = XmlReader.Create(new StringReader(rawMessage));
MessageType message = (MessageType)serializer.Deserialize(reader);

我收到一条错误消息,指出实际元素类型(例如“UpdateParameter”)不是预期的。

目前我能想到的唯一解决方案是使用 switch 语句:

XmlReader 阅读器 = XmlReader.Create(new StringReader(upString)); reader.MoveToContent(); 开关 (reader.LocalName.ToLower()) 案例“更新参数”: 序列化器 = 新 XmlSerializer(typeof(UpdateParameter)); doStuff((UpdateParameter)serializer.Deserialize(xml)); 休息; 案例“更新参数响应”: 序列化器 = 新 XmlSerializer(typeof(UpdateParameterResponse)); doStuff((UpdateParameterResponse)serializer.Deserialize(xml)); 休息; 案例“更新状态响应”: 序列化器 = 新 XmlSerializer(typeof(UpdateStatusResponse)); doStuff((UpdateStatusResponse)serializer.Deserialize(xml)); 休息; //...等等。对所有可能的元素重复

但如果有一个优雅的解决方案,我真的不想这样做。我想做的是类似

Type rootType = Type.GetType(reader.localName);// 如果名字正确就可以工作
序列化器 = 新 XmlSerializer(typeof(rootType)); // 会工作
doStuff((rootType)serializer.Deserialize(xml)); // 不会工作

但正如 cmets 所指出的,它至少不起作用,因为您似乎无法使用类型变量进行转换。此外,虽然 xml 元素的 localName does 与对象的本地名称匹配,但上述方法需要(据我所知)程序集限定名称,这完全是另一种野兽。请注意,理想情况下会重载 doStuff 方法。

我是否缺少一个优雅的解决方案?或者至少是一个不涉及无休止 switch 语句的解决方案?

【问题讨论】:

你能发布一个 XML 文件格式的 sn-p 吗? 【参考方案1】:

问题How do I use an XmlSerializer to deserialize an object that might be of a base or derived class without knowing the type beforehand?中讨论的相同问题。

My answer here

【讨论】:

谢谢!我在搜索时没有看到那个。

以上是关于当元素可能是许多可能元素之一时,将 XML 元素反序列化为对象的主要内容,如果未能解决你的问题,请参考以下文章

使用本机反应将其他元素推离屏幕的长文本

如何将 xml 元素值反序列化为 C# 类属性

Xml 反序列化 - 将两个元素合并到一个 List<T> 对象中

将子XML元素反序列化为XML字符串

C# xml 反序列化不会将子元素提取到列表中

C# 使用多个可能的命名空间反序列化 xml