C#Xml序列化列表后代与Xml属性

早上好,

我有一个从List下降并拥有公共属性的集合。 Xml序列化程序没有取得我的优势。 列表项序列化很好。 我尝试过XmlAttribute属性无济于事。 你们有解决方案吗?

public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { var people = new PersonCollection { new Person { FirstName="Sue", Age=17 }, new Person { FirstName="Joe", Age=21 } }; people.FavoritePerson = "Sue"; var x = new XmlSerializer(people.GetType()); var b = new StringBuilder(); var w = XmlTextWriter.Create(b, new XmlWriterSettings { NewLineChars = "\r\n", Indent = true }); x.Serialize(w, people); var s = b.ToString(); } } [XmlRoot(ElementName="People")] public class PersonCollection : List { //DOES NOT WORK! ARGHHH [XmlAttribute] public string FavoritePerson { get; set; } } public class Person { [XmlAttribute] public string FirstName { get; set; } [XmlAttribute] public int Age { get; set; } } 

我得到以下xml

      

我想得到这个

      

我继续通过实现IXmlSerializable来解决问题。 如果存在更简单的解决方案,请发布!

  [XmlRoot(ElementName="People")] public class PersonCollection : List, IXmlSerializable { //IT WORKS NOW!!! Too bad we have to implement IXmlSerializable [XmlAttribute] public string FavoritePerson { get; set; } public System.Xml.Schema.XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { FavoritePerson = reader[0]; while (reader.Read()) { if (reader.Name == "Person") { var p = new Person(); p.FirstName = reader[0]; p.Age = int.Parse( reader[1] ); Add(p); } } } public void WriteXml(XmlWriter writer) { writer.WriteAttributeString("FavoritePerson", FavoritePerson); foreach (var p in this) { writer.WriteStartElement("Person"); writer.WriteAttributeString("FirstName", p.FirstName); writer.WriteAttributeString("Age", p.Age.ToString()); writer.WriteEndElement(); } } } 

这不是问题的答案,但我想我会提出一个简化代码开发的建议。

将新的Add方法AddPersonCollection类中:

 public class PersonCollection : List, IXmlSerializable { ... public void Add(string firstName, int age) { this.Add(new Person(firstName, age)); } ... } 

然后,通过执行此操作,您可以将集合初始化程序语法简化为:

 var people = new PersonCollection { { "Sue", 17 }, { "Joe", 21 } }; people.FavoritePerson = "Sue"; 

如果您不介意必须包装所有列表函数,那么您可以将列表嵌入为类的属性而不是从中派生。

然后,您将使用XmlElement属性强制将xml元素写为平面列表(而不是嵌套)。