#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]