Десериализация коллекции с помощью XmlSerialize приводит к пустой коллекции - PullRequest
2 голосов
/ 12 января 2012

Я пытаюсь десериализовать следующий XML-документ:

<?xml version="1.0" encoding="utf-8" ?>
<TestPrice>
  <Price>
    <A>A</A>
    <B>B</B>
    <C>C</C>     
    <Intervals>
      <Interval>
        <A>A</A>
        <B>B</B>
        <C>C</C>
      </Interval>
      <Interval>
        <A>A</A>
        <B>B</B>
        <C>C</C>
      </Interval>
    </Intervals>
  </Price>
</TestPrice>

И у меня есть три класса для десериализации этого в граф объектов:

public class TestPrice
{
    private List<Price> _prices = new List<Price>();
    public List<Price> Price 
    { 
        get { return _prices; }
        set { _prices = value; }
    }
}

public class Price
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }

    private List<Interval> _intervals = new List<Interval>();
    public List<Interval> Intervals
    {
        get { return _intervals; }
        set { _intervals = value; }
    }
}

public class Interval
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
}

Я могу десериализовать каждую часть хорошо. То есть я могу сделать:

var serializer = new XmlSerializer(typeof(Price));
var priceEntity = ((Price)(serializer.Deserialize(XmlReader.Create(stringReader))));

И priceEntity правильно инициализируются с данными XML, содержащимися в stringReader, включая List<Interval> Intervals. Однако если я попытаюсь десериализовать экземпляр TestPrice, он всегда будет содержать пустой List<Price> Price.

Если я изменю определение TestPrice следующим образом:

public class TestPrice
{
    public Price Price { get; set; } 
}

Работает. но, конечно, мой XSD определяет цену как последовательность. У меня есть другие десериализованные объекты, но они не включают последовательности в корневой элемент. Есть ли ограничение, о котором я не знаю? Стоит ли включать какие-то метаданные в TestPrice?

1 Ответ

3 голосов
/ 12 января 2012

Просто украсьте свою коллекцию Price с помощью [XmlElement]:

[XmlElement(ElementName = "Price")]
public List<Price> Price
{
    get { return _prices; }
    set { _prices = value; }
}

Также вы, похоже, десериализуете Price, тогда как корневой тег в вашем XML равен TestPrice.Итак, вот полный пример:

public class TestPrice
{
    [XmlElement(ElementName = "Price")]
    public List<Price> Price { get; set; }
}

public class Price
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }

    public List<Interval> Intervals { get; set; }
}

public class Interval
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
}

class Program
{
    static void Main()
    {
        var xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<TestPrice>
  <Price>
    <A>A</A>
    <B>B</B>
    <C>C</C>
    <Intervals>
      <Interval>
        <A>A</A>
        <B>B</B>
        <C>C</C>
      </Interval>
      <Interval>
        <A>A</A>
        <B>B</B>
        <C>C</C>
      </Interval>
    </Intervals>
  </Price>
</TestPrice>";

        var serializer = new XmlSerializer(typeof(TestPrice));
        using (var reader = new StringReader(xml))
        using (var xmlReader = XmlReader.Create(reader))
        { 
            var priceEntity = (TestPrice)serializer.Deserialize(xmlReader);
            foreach (var price in priceEntity.Price)
            {
                 // do something with the price
            }
        }
    }
}
...