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

时间:2011-01-25 21:17:20

标签: c# xml xml-serialization casting xmlreader

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

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

XmlSerializer serializer = new XmlSerializer(typeof(MessageType));
XmlReader reader = XmlReader.Create(new StringReader(rawMessage));
MessageType message = (MessageType)serializer.Deserialize(reader);

我收到错误,说实际的元素类型(“UpdateParameter”说)不是预期的。

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

XmlReader reader = XmlReader.Create(new StringReader(upString));
reader.MoveToContent();
switch (reader.LocalName.ToLower())
{
   case "updateparameter":
      serializer = new XmlSerializer(typeof(UpdateParameter));
      doStuff((UpdateParameter)serializer.Deserialize(xml));
      break;
   case "updateparameterresponse":
      serializer = new XmlSerializer(typeof(UpdateParameterResponse));
      doStuff((UpdateParameterResponse)serializer.Deserialize(xml));
      break;
   case "UpdateStatusResponse":
      serializer = new XmlSerializer(typeof(UpdateStatusResponse));
      doStuff((UpdateStatusResponse)serializer.Deserialize(xml));
      break;
//...etc. Repeat for all possible elements
}

但如果有一个优雅的解决方案,我真的不愿意这样做。我想做的就像是

Type rootType = Type.GetType(reader.localName);// could work if name is right
serializer = new XmlSerializer(typeof(rootType)); // would work
doStuff((rootType)serializer.Deserialize(xml)); // won't work

但正如评论所指出的那样,它至少不起作用,因为您似乎无法使用类型变量进行转换。此外,当xml元素的localName 与Object的本地名称匹配时,上述方法需要(据我所知)组装限定名称,这是另一个野兽。请注意,理想情况会使doStuff方法过载。

我缺少一个优雅的解决方案吗?或者至少是一个不涉及无限开关语句的解决方案?