Десериализация XML-элемента в Object, когда элемент может быть одним из многих возможных элементов - PullRequest
4 голосов
/ 26 января 2011

В локальной структуре с сообщениями, передаваемыми в XML через pub / sub, мне нужно иметь возможность использовать несколько сообщений, однако все сообщения принимаются в виде простого текста и должны быть десериализованы в объекты, созданные инструментом 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

Но, как отмечается в комментариях, это не работает по крайней мере, потому что вы не можете использовать переменную типа для преобразования. Кроме того, хотя localName элементов xml соответствует , соответствует локальному имени объекта, приведенный выше метод требует (насколько я понимаю) квалифицированного имени сборки, которое вообще является другим зверем. Обратите внимание, что в идеальном случае метод doStuff перегружен.

Есть ли элегантное решение, которое мне не хватает? Или хотя бы решение, которое не включает бесконечные операторы switch?

1 Ответ

...