目前我正在尝试将我的一些类序列化和反序列化为XML。单向(List - > XML)完美运行(参见下面的示例)。另一种方式不能正常工作。 我要反序列化的类包含另一个类的另一个List。这在XML文件中也是正确的。但是当我对课程进行反序列化时,它不会起作用。
在下面的示例中,这意味着类Foo使用其List列表正确序列化。但是,当我反序列化XML-File时,只有FooString,其他属性才能正确序列化。 Bar列表每次都是空的。调试器也无法随时到达那里。
有人能告诉我我做错了吗?
提前致谢!
主要对象如下所示:
[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
// ...
}
(de)序列化类的类:
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 :(得分: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; }
}
}
答案 1 :(得分:0)
哦,该死的!
我看到了我的错误。
通过我的脏“hack”序列化接口对象,它将创建一个临时对象。 XmlSerializer获取临时对象并在那里存储数据。
是否有其他解决方案来序列化和反序列化接口?在Foo类中,我知道它是一个bar实例。但界面强迫我实现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;
}
}
}