2017-04-17 88 views
0

我正在嘗試使用XML序列化和更具體的XmlSerializer設置一個非常小的數據庫。反序列化包含XmlSerializer對象列表的類(c#)

我的主類是以下幾點:

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輸出看起來一致。

的問題發生在反序列化:未報告任何錯誤,但只有第一個列表的第一項處理,第一個列表的下列項目不反序列化,也不是以下列表...

如果我將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; } 
} 
+0

你可以分享(簡化版本)'FooType','BarType'和'ThirdType'來重現問題嗎?沒有[mcve]我們只會猜測。一種可能性:三種缺失類型錯誤地實現了'IXmlSerializable',請參閱https://www.codeproject.com/Articles/43237/How-to-Implement-IXmlSerializable-Correctly – dbc

+0

感謝您的評論,我添加了一個(勉強)簡化列表中使用的類的版本。我試圖在這些類中改變很多東西來試圖縮小問題的範圍,但它看起來與所有類型都是一樣的。沒有任何類型實現IXmlSerializable。 – nrdev

回答

0

DBC實際上是正確的關於他的評論不好IXmlSerializable的實現: 在一個在我的類中,我有一個沒有寫入的類型的屬性,在readXml方法中有問題。

我一開始並沒有看到它,因爲我先後刪除了一些屬性以查看哪一個屬性導致了問題,但是這個屬性仍然存在於第一個反序列化的項目中,因此即使後續項目沒有它,讀者仍然被第一個弄亂了。

現在非常明顯,我首先感到不好意思問這個問題!

非常感謝您的幫助!

相關問題