[英].NET serialization of Array to XML. How to set an alias for array type?
我試圖找出.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<Person[]>(p);
}
static void SerializeObject<T>(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內容:
<ArrayOfPerson>
<Person>
<Firstname>Michael</Firstname>
<Lastname>Jackson</Lastname>
<Age>20</Age>
</Person>
<Person>
<Firstname>Bill</Firstname>
<Lastname>Gates</Lastname>
<Age>21</Age>
</Person>
<Person>
<Firstname>Steve</Firstname>
<Lastname>Jobs</Lastname>
<Age>22</Age>
</Person>
</ArrayOfPerson>
但這不是我想要的。 我希望它看起來像這樣:
<Persons>
<Person>
<Firstname>Michael</Firstname>
<Lastname>Jackson</Lastname>
<Age>20</Age>
</Person>
<Person>
<Firstname>Bill</Firstname>
<Lastname>Gates</Lastname>
<Age>21</Age>
</Person>
<Person>
<Firstname>Steve</Firstname>
<Lastname>Jobs</Lastname>
<Age>22</Age>
</Person>
</Persons>
我怎么能這樣工作呢? 提前致謝!
除了已經提供的建議之外,您只需對代碼進行一些小的更改。
首先,需要重新聲明SerializeObject泛型方法:
// important: declare the input parameter to be an **array** of T, not T.
static void SerializeObject<T>(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
// (e.g., 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<Person[]>(p)
替換為SerializeObject<Person>(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<Person>(p);
}
生成的XML將如下所示:
<Persons>
<Person>
<Firstname>Michael</Firstname>
<Lastname>Jackson</Lastname>
<Age>20</Age>
</Person>
<Person>
<Firstname>Bill</Firstname>
<Lastname>Gates</Lastname>
<Age>21</Age>
</Person>
<Person>
<Firstname>Steve</Firstname>
<Lastname>Jobs</Lastname>
<Age>22</Age>
</Person>
</Persons>
要將<Person>
元素名稱覆蓋為其他名稱,請在類上設置XmlType
屬性,如下所示:
[XmlType("personEntry")]
public class Person
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public uint Age { get; set; }
}
生成的XML如下所示:
<Persons>
<personEntry>
<Firstname>Michael</Firstname>
<Lastname>Jackson</Lastname>
<Age>20</Age>
</personEntry>
<personEntry>
<Firstname>Bill</Firstname>
<Lastname>Gates</Lastname>
<Age>21</Age>
</personEntry>
<personEntry>
<Firstname>Steve</Firstname>
<Lastname>Jobs</Lastname>
<Age>22</Age>
</personEntry>
</Persons>
你需要一個像這樣的容器類:
/// <summary>
/// Represents an Person collection.
/// </summary>
[Serializable]
[XmlRoot("Persons", IsNullable = false)]
public sealed class Persons
{
/// <summary>
/// The person collection.
/// </summary>
private Collection<Person> persons;
/// <summary>
/// Initializes a new instance of the <see cref="Persons"/> class.
/// </summary>
/// <param name="persons">The person list.</param>
public Persons(Collection<Person> persons)
{
this.persons = persons;
}
/// <summary>
/// Initializes a new instance of the <see cref="Persons"/> class.
/// </summary>
/// <param name="persons">The person array.</param>
public Persons(Person[] persons)
: this(new Collection<Person>(persons))
{
}
/// <summary>
/// Prevents a default instance of the <see cref="Persons"/> class from being created.
/// </summary>
private Persons()
{
}
/// <summary>
/// Copies the collection of Person objects to an array and returns
/// it.
/// </summary>
/// <returns>An array of Person objects based on the
/// collection.</returns>
public Person[] ToArray()
{
Person[] personArray = new Person[this.persons.Count];
this.persons.CopyTo(personArray, 0);
return personArray;
}
/// <summary>
/// Gets or sets the persons.
/// </summary>
/// <value>The persons.</value>
[XmlElement("Person")]
public Collection<Person> ThePersons
{
get
{
return this.persons;
}
set
{
this.persons = value;
}
}
/// <summary>
/// Gets the length of the persons.
/// </summary>
/// <value>The length of the persons.</value>
[XmlIgnore]
public int Length
{
get
{
return this.persons.Count;
}
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>A <see cref="IEnumerator<Person>"/> that can be used to
/// iterate through the collection.</returns>
public IEnumerator<Person> GetEnumerator()
{
return (IEnumerator<Person>)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<Persons>(new Persons(p));
Person[] p2 = DeserializeObject<Persons>("filename.xml").ToArray();
}
解串器方法非常簡單:
static T DeserializeObject<T>(string fileName) where T : class
{
using (FileStream fs = File.OpenRead(fileName))
{
XmlSerializer ser = new XmlSerializer(typeof(T));
return (T)ser.Deserialize(fs);
}
}
static void SerializeObject<T>(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<Person[]>(p, typeof(Person));
您可以通過向序列化程序添加root屬性來實現。 見下文。
static void SerializeObject<T>(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);
}
}
或者,您可以傳入一個名稱選擇的func。 你的代碼就是
SerializeObject<Person[]>(p, per=>p.GetType().Name);
static void SerializeObject<T>(T obj, Func<T,string> 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);
}
}
此外,通過Attributes控制序列化的這個鏈接對我來說一直很有用。
http://msdn.microsoft.com/en-us/library/2baksw0z(v=VS.100).aspx
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.