简体   繁体   English

用XmlSerializer(c#)反序列化包含对象列表的类

[英]Deserialize classes containting lists of objects with XmlSerializer (c#)

I'm trying to set up a very small database using XML serialization and more specifically XmlSerializer. 我正在尝试使用XML序列化,更具体地说是XmlSerializer建立一个非常小的数据库。

My main class is the following : 我的主要课程如下:

public class XmlDB
{
    [XmlIgnore]
    public string FilePath { get; private set; }


    public List<FooType> Foos { get; set; }
    public List<BarType> Bars { get; set; }
    public List<ThirdType> Thirds { get; set; }

    private XmlDB():this(null) { }

    public XmlDB(string strDBPath) {
        this.FilePath = strDBPath;
        this.Foos = new List<FooType>();
        this.Bars = new List<BarType>();
        this.Thirds = new List<ThirdType>();
    }

    public static XmlDB Load(string strDBPath) {
        using (XmlReader reader = XmlReader.Create(strDBPath)) {
            XmlDB db = (XmlDB)new XmlSerializer(typeof(XmlDB)).Deserialize(reader);
            db.FilePath = strDBPath;
            return db;
        }
    }

    public void SaveChanges() {
        XmlWriterSettings settings = new XmlWriterSettings() {
            Indent = true,
            Encoding = Encoding.UTF8
        };
        using (XmlWriter writer = XmlWriter.Create(this.FilePath, settings)) {
            XmlSerializer ser = new XmlSerializer(typeof(XmlDB));
            ser.Serialize(writer, this);
        }
    }
}

My test method creates an instance, populates the lists and calls the SaveChanges method. 我的测试方法创建一个实例,填充列表并调用SaveChanges方法。 Everything works fine on serialization and the Xml output looks consistent. 序列化时一切正常,Xml输出看起来一致。

The problem happens on deserializing : No error is reported but only the first item of the first List is treated, the following items of the first list are not deserialized, neither are the following lists... 反序列化时发生问题:未报告任何错误,但仅处理了第一个列表的第一个项目,不对第一个列表的以下项目进行反序列化,以下列表也没有...

If I shuffle the order of the lists in the Xml, it's always the first item of the first list in the Xml file that is deserialized. 如果我重新排列Xml中列表的顺序,则它始终是反序列化的Xml文件中第一个列表的第一项。

I tried the following simple test to confirm (which unfortunately works fine, all lists are populated on deserializing) : 我尝试了以下简单测试来确认(不幸的是,它可以正常工作,所有列表都在反序列化时填充):

public class DBTestList
{
    public List<DBTest> TestList { get; set; }
    public List<DBTest2> TestList2 { get; set; }

    public DBTestList() {
        this.TestList = new List<DBTest>();
        this.TestList2 = new List<DBTest2>();
    }
}

public class DBTest
{
    public int TestInt { get; set; }
    public string TestStr { get; set; }
}

public class DBTest2
{
    public int TestInt { get; set; }
    public string TestStr { get; set; }
}

public void TestSerialProblem() {
    //Init data
    DBTestList tl = new DBTestList();
    tl.TestList.Add(new DBTest() { TestInt = 1, TestStr = "test11" });
    tl.TestList.Add(new DBTest() { TestInt = 2, TestStr = "test12" });
    tl.TestList2.Add(new DBTest2() { TestInt = 3, TestStr = "test21" });

    XmlWriterSettings settings = new XmlWriterSettings() {
        Indent = true,
        Encoding = Encoding.UTF8
    };
    using (XmlWriter writer = XmlWriter.Create("test.db", settings)) {
        XmlSerializer ser = new XmlSerializer(typeof(DBTestList));
        ser.Serialize(writer, tl);
    }

    using (XmlReader reader = XmlReader.Create("test.db")) {
        DBTestList db = (DBTestList)new XmlSerializer(typeof(DBTestList)).Deserialize(reader);
        Assert.IsTrue(db.TestList2[0].TestStr == "test21");
    }
}

I read a lot of posts on this subject but none helped. 我读了很多关于该主题的文章,但没有帮助。 Do you have an idea ? 你有想法吗 ?

Thanks, Best regards. 谢谢,最好的问候。

EDIT : To give a more detailed idea of the classes used in the lists, here's one basic implementation. 编辑:为了更详细地说明列表中使用的类,这是一个基本的实现。 All the types are derived from the parent one a_SolidElement, adding only a few properties (basic value types and/or enum) : 所有类型都是从父级a_SolidElement派生的,仅添加一些属性(基本值类型和/或枚举):

public abstract class a_SolidElement
{
    [XmlIgnore]
    public int Position { get; set; }

    public virtual double Thickness { get; set; }
    public virtual double Density { get; set; }

    public string SupplierName { get; set; }
    public string Name { get; set; }
}

public enum ElementType
{
    Undefined=0,
    TypeA,
    TypeB
}

public class FooType:a_SolidElement
{
    public double AdditionalData { get; set; }

    public e_ElementType ElementType { get; set; }
}

dbc was actually right about the bad IXmlSerializable implementation in his comment : In one of my classes, I had one property of a type I didn't write, with a problem in the readXml method. dbc在他的评论中实际上对错误的IXmlSerializable实现是正确的:在我的一个类中,我有一个我没有写的类型的属性,在readXml方法中有问题。

I didn't see it at first because I successively removed some properties to see which one caused the problem but this one was still in the first deserialized item so that even if the subsequent ones didn't have it, the reader was still already messed up by the first one. 一开始我没有看到它,因为我先后删除了一些属性以查看哪个问题引起了问题,但是该属性仍在第一个反序列化的项目中,因此即使后续的项目都不存在,读者仍然很困惑由第一个。

It's so obvious now that I feel bad for asking the question in the first place ! 现在是如此明显,以至于我一开始就问这个问题感到很沮丧!

Thank you very much for the help ! 非常感谢你的帮助 !

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM