.NET序列化为XML。 如何为数组类型设置别名?

我试图找出.net数组到XML的序列化。 这是我提出的一段代码:

public class Program { public class Person { public string Firstname { get; set; } public string Lastname { get; set; } public uint Age { get; set; } } static void Main () { Person[] p = { new Person{Age = 20, Firstname = "Michael", Lastname = "Jackson"}, new Person{Age = 21, Firstname = "Bill", Lastname = "Gates"}, new Person{Age = 22, Firstname = "Steve", Lastname = "Jobs"} }; SerializeObject(p); } static void SerializeObject(T obj) where T : class { string fileName = Guid.NewGuid().ToString().Replace("-", "") + ".xml"; using (FileStream fs = File.Create(fileName)) { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlSerializer ser = new XmlSerializer(typeof(T)); ser.Serialize(fs, obj, ns); } } } 

以下是此示例写入XML文件的XML内容:

   Michael Jackson 20   Bill Gates 21   Steve Jobs 22   

但这不是我想要的。 我希望它看起来像这样:

   Michael Jackson 20   Bill Gates 21   Steve Jobs 22   

我怎么能这样工作呢? 提前致谢!

除了已经提供的建议之外,您只需对代码进行一些小的更改。

首先,需要重新声明SerializeObjectgenerics方法:

 // important: declare the input parameter to be an **array** of T, not T. static void SerializeObject(T[] obj) where T : class { string fileName = Guid.NewGuid().ToString().Replace("-", "") + ".xml"; using (FileStream fs = File.Create(fileName)) { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); // override default root node name. based on your question, // i'm just going to append an "s" to the base type // (eg, Person becomes Persons) var rootName = typeof(T).Name + "s"; XmlRootAttribute root = new XmlRootAttribute(rootName); // add the attribute to the serializer constructor... XmlSerializer ser = new XmlSerializer(obj.GetType(), root); ser.Serialize(fs, obj, ns); } } 

其次,在Main()方法中,将SerializeObject(p)替换为SerializeObject(p) 。 因此,您的Main()方法将如下所示:

 static void Main(string[] args) { Person[] p = { new Person{Age = 20, Firstname = "Michael", Lastname = "Jackson"}, new Person{Age = 21, Firstname = "Bill", Lastname = "Gates"}, new Person{Age = 22, Firstname = "Steve", Lastname = "Jobs"} }; SerializeObject(p); } 

生成的XML将如下所示:

   Michael Jackson 20   Bill Gates 21   Steve Jobs 22   

要将元素名称覆盖为其他名称,请在类上设置XmlType属性,如下所示:

 [XmlType("personEntry")] public class Person { public string Firstname { get; set; } public string Lastname { get; set; } public uint Age { get; set; } } 

生成的XML如下所示:

   Michael Jackson 20   Bill Gates 21   Steve Jobs 22   

你需要一个像这样的容器类:

  ///  /// Represents an Person collection. ///  [Serializable] [XmlRoot("Persons", IsNullable = false)] public sealed class Persons { ///  /// The person collection. ///  private Collection persons; ///  /// Initializes a new instance of the  class. ///  /// The person list. public Persons(Collection persons) { this.persons = persons; } ///  /// Initializes a new instance of the  class. ///  /// The person array. public Persons(Person[] persons) : this(new Collection(persons)) { } ///  /// Prevents a default instance of the  class from being created. ///  private Persons() { } ///  /// Copies the collection of Person objects to an array and returns /// it. ///  /// An array of Person objects based on the /// collection. public Person[] ToArray() { Person[] personArray = new Person[this.persons.Count]; this.persons.CopyTo(personArray, 0); return personArray; } ///  /// Gets or sets the persons. ///  /// The persons. [XmlElement("Person")] public Collection ThePersons { get { return this.persons; } set { this.persons = value; } } ///  /// Gets the length of the persons. ///  /// The length of the persons. [XmlIgnore] public int Length { get { return this.persons.Count; } } ///  /// Returns an enumerator that iterates through the collection. ///  /// A  that can be used to /// iterate through the collection. public IEnumerator GetEnumerator() { return (IEnumerator)this.persons.GetEnumerator(); } } 

使用完成的数组初始化它并按照Main()方法返回它:

  static void Main () { Person[] p = { new Person{Age = 20, Firstname = "Michael", Lastname = "Jackson"}, new Person{Age = 21, Firstname = "Bill", Lastname = "Gates"}, new Person{Age = 22, Firstname = "Steve", Lastname = "Jobs"} }; SerializeObject(new Persons(p)); Person[] p2 = DeserializeObject("filename.xml").ToArray(); } 

解串器方法非常简单:

  static T DeserializeObject(string fileName) where T : class { using (FileStream fs = File.OpenRead(fileName)) { XmlSerializer ser = new XmlSerializer(typeof(T)); return (T)ser.Deserialize(fs); } } 

选项2(基于Nix的回答 ):

  static void SerializeObject(T obj, Type t) where T : class { string fileName = Guid.NewGuid().ToString().Replace("-", "") + ".xml"; using (FileStream fs = File.Create(fileName)) { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlRootAttribute root = new XmlRootAttribute(t.Name + "s"); XmlSerializer ser = new XmlSerializer(typeof(T), root); ser.Serialize(fs, obj, ns); } } 

可以这样称呼:

  SerializeObject(p, typeof(Person)); 

此外,通过Attributes控制序列化的这个链接对我来说一直很有用。

http://msdn.microsoft.com/en-us/library/2baksw0z(v=VS.100).aspx

您可以通过向序列化程序添加root属性来完成此操作。 见下文。

  static void SerializeObject(T obj) where T : class { string fileName = Guid.NewGuid().ToString().Replace("-", "") + ".xml"; using (FileStream fs = File.Create(fileName)) { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlRootAttribute root = new XmlRootAttribute( typeof(T).Name + "s"); XmlSerializer ser = new XmlSerializer(typeof(Person[]), root); ser.Serialize(fs, obj, ns); } } 

或者,您可以传入一个选择名称的函数。 你的代码就是

  SerializeObject(p, per=>p.GetType().Name); static void SerializeObject(T obj, Func nameSelector) where T : class { string fileName = Guid.NewGuid().ToString().Replace("-", "") + ".xml"; using (FileStream fs = File.Create(fileName)) { XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("", ""); XmlRootAttribute root = new XmlRootAttribute(nameSelector(obj)); XmlSerializer ser = new XmlSerializer(typeof(Person[]), root); ser.Serialize(fs, obj, ns); } }