Как десериализовать XML-массив, содержащий несколько типов элементов в С# - программирование
Подтвердить что ты не робот

Как десериализовать XML-массив, содержащий несколько типов элементов в С#

Я пытаюсь десериализовать следующий файл:

<league>
    <players>
        <skater>
            <name>Wayne Stamkos</name>
            <goals>23</goals>
            <assists>34</assists>
        </skater>
        <skater>
            <name>Sidney Lindros</name>
            <goals>41</goals>
            <assists>44</assists>
        </skater>
        <goalie>
            <name>Martin Roy</name>
            <wins>15</wins>
            <losses>12</losses>
        </goalie>
        <skater>
            <name>Paul Forsberg</name>
            <goals>21</goals>
            <assists>51</assists>
        </skater>
        <goalie>
            <name>Roberto Rinne</name>
            <wins>18</wins>
            <losses>23</losses>
        </goalie>
    </players>
</league>

Со следующим кодом:

namespace ConsoleApplication2
{
    [XmlRoot("league")]
    public class League
    {
        [XmlArray("players")]
        [XmlArrayItem("skater")]
        public List<Skater> skaters { get; set; }
        [XmlArrayItem("goalie")]
        public List<Goalie> goalies { get; set; }
    }

    public class Skater
    {
        [XmlElement("name")]
        public string Name;
        [XmlElement("goals")]
        public int Goals;
        [XmlElement("assists")]
        public int Assists;
    }

    public class Goalie
    {
        [XmlElement("name")]
        public string Name;
        [XmlElement("wins")]
        public int Wins;
        [XmlElement("losses")]
        public int Losses;
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (FileStream reader = new FileStream(@"C:\Temp\test.xml", FileMode.Open, FileAccess.Read))
            {
                var ser = new XmlSerializer(typeof(League));
                League league = (League)ser.Deserialize(reader);
            }
        }
    }
}

Я ожидаю вернуть объект Лиги, содержащий список Skaters с тремя элементами и список Goalies с 2 элементами. Я получаю ожидаемый список фигуристов, но список Goalies пуст. Что я делаю неправильно?

4b9b3361

Ответ 1

Есть два способа сделать это; первый должен сделать что-то вроде:

[XmlArray("players")]
[XmlArrayItem("skater", Type=typeof(Skater))]
[XmlArrayItem("goalie", Type=typeof(Goalie))]
public List<SomeCommonBaseClass> Players { get; set; }

который отображает два типа элементов внутри одной коллекции. В худшем случае SomeCommonBaseClass может быть object:

[XmlArray("players")]
[XmlArrayItem("skater", Type=typeof(Skater))]
[XmlArrayItem("goalie", Type=typeof(Goalie))]
public List<object> Players { get; set; }

Во-вторых, сделать <players> карту объекту-обертки:

[XmlElement("players")]
public Players Players { get;set;}
...
public class Players
{
    [XmlElement("skater")]
    public List<Skater> Skaters {get;set;}

    [XmlElement("goalie")]
    public List<Goalie> Goalies {get;set;}
}

Выбор зависит от обстоятельств; последний допускает такие вещи, как "не более одного вратаря", меняя его на:

    [XmlElement("goalie")]
    public Goalie Goalie {get;set;}