【问题标题】:XmlSerializer not deserializing XML to IEnumerableXmlSerializer 未将 XML 反序列化为 IEnumerable
【发布时间】:2019-12-30 19:40:16
【问题描述】:

在引用 Stack Overflow 的一篇帖子 XmlSerializer won't serialize IEnumerable 时,我有以下代码可以正确序列化为 XML,但是当反序列化回来时,IEnumerable 会返回为空。

using System.Xml.Linq;
using System.Xml.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;

public class Hello{
    public static void Main(){

        // <!--- Serializing part -->
        Glossary glossary1 = new Glossary();
        glossary1.Term = "Test1";
        glossary1.Definition = "Test1";
        Glossary glossary2 = new Glossary();
        glossary2.Term = "Test2";
        glossary2.Definition = "Test2";
        List<Glossary> glossaryList = new List<Glossary>();
        glossaryList.Add(glossary1);
        glossaryList.Add(glossary2);
        GlossaryCollection glossary = new GlossaryCollection(glossaryList);

        XDocument doc = new XDocument();
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(GlossaryCollection));
        using (var writer = doc.CreateWriter()) {
            xmlSerializer.Serialize(writer, glossary);
        }

        doc.Save("test.xml");
        XDocument doc2 = XDocument.Load("test.xml");
        Console.WriteLine(glossary.glossaryList.Count());
        Console.WriteLine(doc2.ToString());
        //So far looks good - serializing works fine!
        // </!--- Serializing part -->      
        // <!--- De-Serializing part -->                

        GlossaryCollection temp2;
        xmlSerializer = new XmlSerializer(typeof(GlossaryCollection));
        using (var reader = doc2.Root.CreateReader()) {
            var temp = xmlSerializer.Deserialize(reader);
            temp2 = (GlossaryCollection) temp;
        }

        Console.WriteLine(temp2.glossaryList.Count()); // Results in 0, should be 2... :(
        // </!--- De-Serializing part -->               
    }
    [XmlRoot]
            public class GlossaryCollection {
                [XmlIgnore]
                    public IEnumerable<Glossary> glossaryList;
                [XmlElement]    
                    public List<Glossary> GlossarySurrogate { get { return glossaryList.ToList(); } set { glossaryList = value; } }  // https://stackoverflow.com/questions/9102234/xmlserializer-wont-serialize-ienumerable   
                public GlossaryCollection() {
                    glossaryList = new List<Glossary>();
                }
                public GlossaryCollection(IEnumerable<Glossary> glossaryList) {
                    this.glossaryList = glossaryList;
                }
            }
        [XmlType("Glossary")]
                public class Glossary
                {
                        public string Id { get; set; }
                        public string Term { get; set; }
                        public string Definition { get; set; }
                }   
}

更新:根据 Iridium 的回答,似乎不可能将 IEnumerable 与 XmlSerializer 一起使用,因为它每次都返回一个新列表,因此采用了转换为列表的方法。但是,如果有一个解决方案(即使是 hacky)将词汇表保持为 IEnumerable,请告诉我 - 即使只是出于好奇。

【问题讨论】:

  • Xmlnclude 表示另一个类可以继承基类。所以如果你有 [XmlInclude(typeof(Glossary))] 那么你应该有 Glossary : GlossaryCollection.如果你有 [XmlInclude(typeof(GlossaryCollection))] 那么你应该有 GlossaryCollection : Glossary.现在你怎么能让一个孩子继承父母,而同一个父母继承孩子?
  • @jdweng 很好,非常感谢

标签: c# xml-serialization xmlserializer


【解决方案1】:

当你的 XML 序列化类型有一个 List&lt;T&gt; 类型的属性时,XmlSerializerget 属性的值,然后调用 .Add(...) 来添加反序列化的元素(即它确实set 属性)。

由于GlossarySurrogate 属性的getter 每次get 都会返回一个新列表,因此XML 序列化程序对结果所做的更改将丢失。

如果您希望它正常工作,您需要将您的 glossaryList 字段转换为 List&lt;Glossary&gt; 并直接从 GlossarySurrogate getter 返回,而无需对其调用 .ToList()

【讨论】:

    猜你喜欢
    • 2023-04-05
    • 2020-12-09
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多