В локальной структуре с сообщениями, передаваемыми в 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?