2015-07-11 68 views
0

当前我试图序列化并反序列化一些我的类到XML。一种方式(列表 - > XML)完美工作(请参见下面的示例)。另一种方式将无法正常工作。 我想要反序列化的类包含另一个类的另一个列表。这在XML文件中也是正确的。但是当我反序列化这个类时,它将不起作用。XML(De)列表序列化

在下面的例子中,这意味着Foo类可以通过其List of Bars正确地序列化。但是,当我反序列化的XML文件只有FooString和其他属性被正确序列化。酒吧名单每次都是空的。调试器也不会随时进入。

有人能告诉我我做错了什么吗?

在此先感谢!

主被摄体看起来像这样:

[XmlInclude(typeof (Bar))] 
[XmlRoot(ElementName = "Foo")] 
public class Foo() : IFooInterface 
{ 
    [XmlElement("FooString")] 
    public string FooString 
    { 
     // For simplifaction auto proerty, normally with 
     // backing field 
     get; 
     set; 
    } 

    // Some other properties for the xml 
    // ... 

    // Dirty Hack to serialize the List, because an Interface could not be serialized 
    // I've already tried to remove this tag, to replace it with [XmlElement("BarList")], but nothing works 
    [XmlArray("BarList")] 
    [XmlArrayItem(ElementName = "Bar", Type = typeof(Bar))] 
    public List<Bar> XmlBarList 
    { 
     get 
     { 
      return this.BarList.Select(bar => bar as Bar).ToList(); 
     } 
     set 
     { 
      this.BarList = new ObservableCollection<IBarInterface>(value); 
     } 
    } 

    private ObservableCollection<IBarInterface> barList; 

    [XmlIgnore] 
    public ObservableCollection<IBarInterface> BarList 
    { 
     get 
     { 
      return this.barList; 
     } 
     set 
     { 
      // For simplification removed Notification Proerties 
      this.barList = value; 
     } 
    } 
} 

嵌套类看起来像这样:

[XmlType("Bar")] 
public class Bar : IBarInterface 
{ 
    [XmlElement("BarString")] 
    public string BarString 
    { 
     get; 
     set; 
    } 

    // Some other properties for the xml 
    // ... 
} 

该(解)序列化的类的类:

public class FooBarProvider() 
{ 
    // Won't work 
    // the BarList of any Foo item is everytime 
    // empty. 
    public List<Foo> Load() 
    { 
     var reader = new StreamReader("PathToTheXml.xml"); 
     var serializer = new XmlSerializer(typeof(List<Foo>)); 
     var list = (List<Foo>)serializer.Deserialize(reader); 
    } 

    // Works 
    public void Save(List<Foo> fooList) 
    { 
     var serializer = new XmlSerializer(typeof(List<Foo>)); 
     var writer = new StreamWriter("PathToTheXml.xml"); 
     serializer.Serialize(writer, fooList); 
     writer.Close(); 
    } 
} 

这是生成的XML文件:

<ArrayOfFoo xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Foo> 
    <BarList> 
     <Bar> 
     <BarString>Hello Bar!</BarString> 
     </Bar> 
    </BarList> 
    <FooString>Hello Foo!</FooString> 
    </Foo> 
</ArrayOfFoo> 

回答

0

不要使用XmlArray。它创建了一组额外的节点。改用XmlElement。

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 

      ArrayOfFoo aof = new ArrayOfFoo() { 
       foo = new Foo() { 
        FooString = "Hello Foo!", 
        barList = new List<BarList>() { 
         new BarList() { 
          bar = new Bar() { 
           barString = "Hello Bar!" 
          } 
         } 
        } 
       } 
      }; 

      XmlSerializer serializer = new XmlSerializer(typeof(ArrayOfFoo)); 

      StreamWriter writer = new StreamWriter(FILENAME); 
      serializer.Serialize(writer, aof); 
      writer.Flush(); 
      writer.Close(); 
      writer.Dispose(); 

      XmlSerializer xs = new XmlSerializer(typeof(ArrayOfFoo)); 
      XmlTextReader reader = new XmlTextReader(FILENAME); 
      ArrayOfFoo newAof = (ArrayOfFoo)xs.Deserialize(reader); 
     } 
    } 
    [XmlRoot(ElementName = "ArrayOfFoo")] 
    public class ArrayOfFoo 
    { 
     [XmlElement("Foo")] 
     public Foo foo { get; set; } 
    } 

    [XmlRoot(ElementName = "Foo")] 
    public class Foo 
    { 
     [XmlElement("FooString")] 
     public string FooString { get; set; } 


     [XmlElement("BarList")] 
     public List<BarList> barList { get; set; } 

    } 


    [XmlRoot(ElementName = "BarList")] 
    public class BarList 
    { 
     [XmlElement("Bar")] 
     public Bar bar { get; set; } 
    } 


    [XmlRoot(ElementName = "Bar")] 
    public class Bar 
    { 
     [XmlElement("BarString")] 
     public string barString { get; set; } 
    } 
    [XmlRoot(ElementName = "BarString")] 
    public class BarString 
    { 
     [XmlText] 
     public string value { get; set; } 
    }​ 
} 
​ 
+0

您好,感谢您的回复。但是这也没有奏效。我试过了。我也尝试删除标签,并让它自动决定。但是我所做的一切 - 它不会奏效:/你有另一种方法吗? – CodeRain

+0

更新的代码。应该工作 – jdweng

+0

谢谢你的工作:) – CodeRain

0

哦该死的!

我看到我的错误。

通过我的肮脏的“黑客”序列化接口对象它将创建一个临时对象。 XmlSerializer接受临时对象并在那里存储数据。

是否有任何其他解决方案来序列化和反序列化接口?在Foo课上,我知道它是一个酒吧的例子。但是界面迫使我实现IBarInterface的列表。

Foo的接口:

public interface IFooInterface 
{ 
    ObservableCollection<IBarInterface> BarList { get; } 
} 

IFooInterface的实现:

[XmlInclude(typeof(Bar))] 
[XmlRoot(ElementName ="Foo")] 
public class Foo : IFooInterface 
{ 
    ObservableCollection<IBarInterface> barList; 

    [XmlElement(ElementName ="BarList")] 
    public ObservableCollection<Bar> XmlBarList 
    { 
     get 
     { 
      // Creates an temporary Object, so it won't work 
      return this.BarList.Select(bar => bar as Bar).ToList(); 
     } 
     set 
     { 
      this.BarList = new ObservableCollection<IBarInterface>(value); 
     } 
    } 

    // Won't work out of the box with XmlSerializer 
    // so I Ignore it 
    [XmlIgnore] 
    ObservableCollection<IBarInterface> BarList 
    { 
     get 
     { 
      return this.barList; 
     } 
     set 
     { 
      this.barList = value; 
     } 
    } 
} 

Bar的接口:

public interface IBarInterface 
{ 
    string BarString { get; } 
} 

IBarInterface实现:

[XmlRoot(ElementName ="Bar")] 
public class Bar : IBarInterface 
{ 
    string BarString; 

    [XmlElement(ElementName = "BarString")] 
    string BarString 
    { 
     get 
     { 
      return this.bar; 
     } 
     set 
     { 
      this.bar = value; 
     } 
    } 
}