【问题标题】:C# Xml Serializing List<T> descendant with Xml Attribute具有 Xml 属性的 C# Xml 序列化 List<T> 后代
【发布时间】:2023-03-08 06:40:01
【问题描述】:

早安,

我有一个来自 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<Person>
{
    //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

<?xml version="1.0" encoding="utf-16"?>
        <People xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <Person FirstName="Sue" Age="17" />
          <Person FirstName="Joe" Age="21" />
        </People>

我想要这个

<?xml version="1.0" encoding="utf-16"?>
        <People FavoritePerson="Sue" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <Person FirstName="Sue" Age="17" />
          <Person FirstName="Joe" Age="21" />
        </People>

【问题讨论】:

    标签: c# list attributes generics xmlserializer


    【解决方案1】:

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

        [XmlRoot(ElementName="People")]
    public class PersonCollection : List<Person>, 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();            
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      PersonCollection 类添加一个新的Add 方法,如下所示:

      public class PersonCollection : List<Person>, 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";
      

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          猜你喜欢
          • 2010-11-17
          • 2017-11-07
          • 2016-03-17
          • 2023-04-07
          • 2011-09-28
          • 1970-01-01
          • 1970-01-01
          • 2020-10-16
          • 1970-01-01
          相关资源
          最近更新 更多