【问题标题】:Deserialize classes containting lists of objects with XmlSerializer (c#)使用 XmlSerializer (c#) 反序列化包含对象列表的类
【发布时间】:2017-09-13 07:20:59
【问题描述】:

我正在尝试使用 XML 序列化尤其是 XmlSerializer 设置一个非常小的数据库。

我的主要课程如下:

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);
        }
    }
}

我的测试方法创建一个实例,填充列表并调用 SaveChanges 方法。 序列化时一切正常,Xml 输出看起来一致。

反序列化时出现问题:不报错但只处理第一个List的第一项,第一个列表的以下项没有反序列化,以下列表也没有......

如果我打乱 Xml 中列表的顺序,反序列化的始终是 Xml 文件中第一个列表的第一项。

我尝试了以下简单的测试来确认(不幸的是,它工作正常,所有列表都在反序列化时填充):

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");
    }
}

我阅读了很多关于这个主题的帖子,但没有任何帮助。 你有什么想法吗?

谢谢, 最好的问候。

编辑: 为了更详细地了解列表中使用的类,这里有一个基本实现。 所有类型都派生自父级 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; }
}

【问题讨论】:

  • 您能否分享(简化版)FooTypeBarTypeThirdType 以重现该问题?如果没有minimal reproducible example,我们只能猜测。一种可能:三个缺失的类型错误地实现了IXmlSerializable,见codeproject.com/Articles/43237/…
  • 感谢您的评论,我添加了列表中使用的类的(几乎)简化版本。我尝试在这些类中更改很多内容以尝试缩小问题范围,但看起来所有类型都相同。没有一个类型实现 IXmlSerializable。

标签: c# xml list serialization xmlserializer


【解决方案1】:

dbc 在他的评论中关于错误的 IXmlSerializable 实现实际上是正确的: 在我的一个类中,我有一个类型的属性不是我写的,readXml 方法有问题。

我一开始没看到,因为我接连去掉了一些属性,看看是哪一个导致了问题,但是这个还在第一个反序列化的item中,所以即使后面的没有,读者也是还是被第一个搞砸了。

现在很明显,一开始就问这个问题我感觉很糟糕!

非常感谢您的帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-21
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 2012-09-06
    相关资源
    最近更新 更多