【问题标题】:Deserializing a collection with XmlSerialize results in empty collection使用 XmlSerialize 反序列化集合会导致空集合
【发布时间】:2012-02-08 06:27:09
【问题描述】:

我正在尝试反序列化以下 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 使用包含在stringReader 中的XML 数据正确初始化,包括List&lt;Interval&gt; Intervals。但是,如果我尝试反序列化 TestPrice 实例,它总是会出现一个空的 List&lt;Price&gt; Price

如果我像这样更改TestPrice 的定义:

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

它有效。但当然,我的 XSD 将 Price 定义为一个序列。我有其他实体反序列化很好,但它们不包括根元素中的序列。有我不知道的限制吗?我应该在TestPrice 中包含某种元数据吗?

【问题讨论】:

    标签: c# xml collections xml-deserialization


    【解决方案1】:

    只需使用[XmlElement] 装饰您的 Price 收藏:

    [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
                }
            }
        }
    }
    

    【讨论】:

    • 我按照建议装饰了价格集合并执行了您的示例。我仍然得到一个空的价格集合。顺便说一句,你为什么将一个新的 XmlReader 实例传递给序列化程序,而不是你在 xmlReader 中已有的实例?
    • @Cesar,对不起,这是读者的错误。我已经修复了我的样本。它现在应该可以工作了。
    • 有趣的是,我运行了与您完全相同的代码并且它可以工作。但是,如果我将其调整为我的实际代码,我仍然会得到相同的结果。无论如何,至少我知道它应该可以工作,所以我将其标记为已接受。谢谢!
    • 仅作记录:我不知道我做错了什么,但 Drain 的回答是正确的。终于让它工作了:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    相关资源
    最近更新 更多