XML-сериализация для унаследованных объектов C # - PullRequest
0 голосов
/ 24 октября 2019

У меня есть следующий XML-сценарий:

<al2:Dispatch xmlns:al1="al:1.0.0" xmlns:al2="al:2.0.0">

    <al2:MsgIdentificator>0001</al2:MsgIdentificator>

    ..

    <al1:DispatchReceiverGroup>

        <al2:Receiver>

            <al1:ANumberIdentificator>100001</al1:ANumberIdentificator>
            <al1:BNumberIdentificator>1000000001</al1:BNumberIdentificator>

        </al2:Receiver>

    </al1:DispatchReceiverGroup>

</al2:Dispatch>

Итак, моя модель выглядит следующим образом:

    [Serializable]
    [XmlRoot(Namespace = "al:2.0.0", ElementName = "Dispatch")]
    public class BatchDistribution
    {
        [XmlElement(Namespace = "al:2.0.0", ElementName = "MsgIdentificator")]
        public string MessageIdentificator { get; set; }

        //CONFUSED HERE
        [XmlArray(Namespace = "al:1.0.0", ElementName = "DispatchReceiverGroup")]
        [XmlArrayItem(Namespace = "al:2.0.0", ElementName = "Receiver")]
        public List<DistributionReceiver> DistributionRecievers { get; set; }    
    }
}

Итак, я хочу иметь необязательное количество элементов ANumberIdentificator иBNumberIdentificator элементов. Для этого я создал базовый класс DistributionReceiver, который наследуется DistributionReceiverA и DistributionReceiverB, например:

    [Serializable]
    public class DistributionReceiver
    {
        [XmlElement(Namespace = "al:1.0.0")]    //note i dont assign value for Element name because it has to be decided by sub classes 
        public string NumberIdentificator{ get; set; }
    }

и подклассы:

    [Serializable]
    public class DistributionRecieverA : DistributionReceiver
    {
        [XmlElement(Namespace = "al:1.0.0", ElementName = "ANumberIdentificator")]
        public new string ANumberIdentificator { get; set; }
    }

а другой

    [Serializable]
    public class DistributionRecieverB : DistributionReceiver
    {
        [XmlElement(Namespace = "al:1.0.0", ElementName = "BNumberIdentificator")]
        public new string BNumberIdentificator { get; set; }
    }

Проблема в том, что я не получаю сериализованные ANumberIdentificator и BNumberIdentificator.

Ответы [ 2 ]

1 голос
/ 24 октября 2019

Похоже, что модель неверна для ANumberIdentificator и BNumberIdentificator

Я использовал xmltocsharp для преобразования примера XML, и модель выглядела как

    [XmlRoot(ElementName = "Receiver", Namespace = "al:2.0.0")]
public class Receiver
{
    [XmlElement(ElementName = "ANumberIdentificator", Namespace = "al:1.0.0")]
    public List<string> ANumberIdentificator { get; set; }
    [XmlElement(ElementName = "BNumberIdentificator", Namespace = "al:1.0.0")]
    public List<string> BNumberIdentificator { get; set; }
}

[XmlRoot(ElementName = "DispatchReceiverGroup", Namespace = "al:1.0.0")]
public class DispatchReceiverGroup
{
    [XmlElement(ElementName = "Receiver", Namespace = "al:2.0.0")]
    public Receiver Receiver { get; set; }
}

[XmlRoot(ElementName = "Dispatch", Namespace = "al:2.0.0")]
public class Dispatch
{
    [XmlElement(ElementName = "MsgIdentificator", Namespace = "al:2.0.0")]
    public string MsgIdentificator { get; set; }
    [XmlElement(ElementName = "DispatchReceiverGroup", Namespace = "al:1.0.0")]
    public DispatchReceiverGroup DispatchReceiverGroup { get; set; }
    [XmlAttribute(AttributeName = "al1", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Al1 { get; set; }
    [XmlAttribute(AttributeName = "al2", Namespace = "http://www.w3.org/2000/xmlns/")]
    public string Al2 { get; set; }
}

Я использовал XmlSerializer для преобразования XML в объект

XmlSerializer serializer = new XmlSerializer(typeof(Dispatch));
        using (TextReader reader = new StringReader(xmlstring))
        {
            //convert the xml to object
            Dispatch result = (Dispatch)serializer.Deserialize(reader);
        }

И я могу читать A и B под Receiver

Console.WriteLine(result.DispatchReceiverGroup.Receiver.ANumberIdentificator);

Console.WriteLine(result.DispatchReceiverGroup.Receiver.BNumberIdentificator);
0 голосов
/ 24 октября 2019

XmlArrayItem должен перечислять все возможные типы в вашем массиве

  XmlArrayItem(ElementName="DistributionReceiver", Type=typeof(DistributionReciever)),   
  XmlArrayItem(ElementName="DistributionRecieverA", Type=typeof(DistributionRecieverA)), 
  XmlArrayItem(ElementName="DistributionRecieverB", Type=typeof(DistributionRecieverB)), 

Сериализатор должен завершить, от ElementName до Runtime-Type. (добавьте свое пространство имен самостоятельно). Место XmlArrayItem правильное, но добавьте несколько!

Если ваш базовый класс абстрактный, не создавайте для него XmlArrayItem.

...