Десериализация 2 типов XML с использованием принципов ООП полиморфизма

#c# #oop #xml-parsing #polymorphism #xml-deserialization

Вопрос:

У меня есть 2 типа xml, которые я хотел бы десериализовать в объект. Часть их структуры схожа. Я пытался использовать принцип полиморфизма OO — используя комбинацию virtual new, чтобы сделать ее максимально полезной, но я все еще не могу понять, как это сделать. Вот демонстрация — вы можете видеть, что разница заключается в узле MSGDATA.

ТИП 1 XML:

 lt;MESSAGEgt;  lt;DOCUMENTgt;  lt;MSGHDRgt;  lt;TIME_STAMPgt;2020010100:00:00.000lt;/TIME_STAMPgt;  lt;MESSAGE_NAMEgt;1lt;/MESSAGE_NAMEgt;  lt;/MSGHDRgt;  lt;MSGDATAgt;  lt;ITEMSTYPE_1gt;  lt;ITEMTYPE_1gt;  lt;NAME_OF_TYPE_1gt;TYPE1_AAAAlt;/NAME_OF_TYPE_1gt;  lt;/ITEMTYPE_1gt;  lt;ITEMTYPE_1gt;  lt;NAME_OF_TYPE_1gt;TYPE1_BBBBlt;/NAME_OF_TYPE_1gt;  lt;/ITEMTYPE_1gt;  lt;/ITEMSTYPE_1gt;  lt;/MSGDATAgt;  lt;/DOCUMENTgt;  lt;DOCUMENTgt;  lt;MSGHDRgt;  lt;TIME_STAMPgt;2020010100:00:00.000lt;/TIME_STAMPgt;  lt;MESSAGE_NAMEgt;2lt;/MESSAGE_NAMEgt;  lt;/MSGHDRgt;  lt;MSGDATAgt;  lt;ITEMSTYPE_1gt;  lt;ITEMTYPE_1gt;  lt;NAME_OF_TYPE_1gt;TYPE1_EEEEEElt;/NAME_OF_TYPE_1gt;  lt;/ITEMTYPE_1gt;  lt;ITEMTYPE_1gt;  lt;NAME_OF_TYPE_1gt;TYPE1_FFFFFlt;/NAME_OF_TYPE_1gt;  lt;/ITEMTYPE_1gt;  lt;/ITEMSTYPE_1gt;  lt;/MSGDATAgt;  lt;/DOCUMENTgt; lt;/MESSAGEgt;  

ТИП 2 XML:

 lt;MESSAGEgt;  lt;DOCUMENTgt;  lt;MSGHDRgt;  lt;TIME_STAMPgt;2020010100:00:00.000lt;/TIME_STAMPgt;  lt;MESSAGE_NAMEgt;1lt;/MESSAGE_NAMEgt;  lt;/MSGHDRgt;  lt;MSGDATAgt;  lt;ITEMSTYPE_2gt;  lt;ITEMTYPE_2gt;  lt;NAME_OF_TYPE_2gt;TYPE2_CCCClt;/NAME_OF_TYPE_2gt;  lt;/ITEMTYPE_2gt;  lt;ITEMTYPE_2gt;  lt;NAME_OF_TYPE_2gt;TYPE2_DDDDlt;/NAME_OF_TYPE_2gt;  lt;/ITEMTYPE_2gt;  lt;/ITEMSTYPE_2gt;  lt;/MSGDATAgt;  lt;/DOCUMENTgt; lt;/MESSAGEgt;  

Вот структура данных (я демонстрирую ее только с помощью XML типа 1) — обратите внимание на отношения между Item_1_Message и базовым классом ItemMessage — у них одинаковые документы свойств — но разных типов с отношениями наследования:

/FIXED/

 [XmlRoot("MESSAGE")] public abstract class ItemMessage {  [XmlIgnore]  public virtual Listlt;ItemDocumentgt; Documents {get; set; } }  [XmlRoot("MESSAGE")] public class Item_1_Message : ItemMessage {  [XmlElement("DOCUMENT)]  public new Listlt;Type_1_ItemDocumentgt; Documents {get; set; } }     [XmlRoot(ElementName="MSGHDR")] public class MsgHeader {  [XmlElement("TIME_STAMP")]  public string strTimeStamp {get; set;}    [XmlElement("MESSAGE_NAME")]  public string MessageName {get; set;} }  [XmlRoot("DOCUMENT")] public abstract class ItemDocument {  [XmlElement("MSGHDR")]  public MsgHeader {get; set;} }    /*This is related to TYPE1 XML*/ public class Type_1_ItemDocument : ItemDocument {  [XmlElement("MSGDATA)]  public Type_1_ItemData itemData {get ; set; } }   [XmlRoot(ElementName = "MSGDATA")] public class Type_1_ItemData {  [XmlElement(ElementName = "ITEMSTYPE_1")]  public ItemsType_1 itemstype1 {get; set;} }    [XmlRoot(ElementName = "ITEMSTYPE_1")] public class ItemsType_1 {  [Xmlelement("ITEMTYPE_1")]  public Listlt;Item1gt; items {get ; set;}   }   [XmlRoot(ElementName = "ITEMTYPE_1")] public class Item1 {  [XmlElement(ElementName = "NAME_OF_TYPE_1")]  [JsonProperty("Name")]  public string name {get;set;} }  

Теперь, короче говоря, когда я пытаюсь десериализовать его, как показано ниже:

 XmlSerializer xmls = new XmlSerializer(typeof(Item_1_Message)); var result = xmls.Deserialize(new StringReader(lt;The XML textgt;));  

Я получаю исключение из скрытия базового класса/

РЕШЕНИЕ: в виртуальном свойстве абстрактного класса — я заменил атрибут XmlAttribute на [XmlIgnore]

Ответ №1:

Решение уже обновлено в коде: в виртуальном свойстве абстрактного класса — я заменил атрибут XmlAttribute на [XmlIgnore]