C#中使用DataContractSerializer反序列化多級xml
阿新 • • 發佈:2019-02-19
DataContractSerializer類可以將型別例項序列化成xml或者將xml反序列化為型別例項,具體細節可以參照MSDN官方文件。
最近遇到了使用DataContractSerializer反序列化多級xml檔案為物件的問題,這裡的多級指的是xml檔案中的節點深度大於2,檔案結構如下:
<StudentInfo> <Name>Kevin</Name> <Age>23</Age> <GirlFriend> <Name>Waner</Name> <Location>Sydney</Location> </GirlFriend> </StudentInfo>
可以看到,這裡的節點深度為3,節點深度比較低的序列化和反序列化方法msdn範例已經給出。
首先我們新建一個Student類,用於存放xml檔案中所有節點資訊,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace DeserializeXml { /// <summary> /// Student information from xml file /// </summary> [DataContract(Name = "StudentInfo",Namespace = "")] public class Student { #region properties [DataMember(Name = "Name", Order = 1)] public string Name { get; set; } [DataMember(Name = "Age", Order = 2)] public string Age { get; set; } [DataMember(Name = "GirlFriend", Order = 3)] public GirlFriend GirlFriend { get; set; } #endregion #region public methods public void PrintInfo() { if (GirlFriend != null) { Console.WriteLine("{0} is {1} years old, and his girlfriend is {2}, who is in {3} now.", Name, Age, GirlFriend.Name, GirlFriend.Location); } else if (!string.IsNullOrEmpty(Name)) { Console.WriteLine("Sorry, {0}'s world is empty.", Name); } else { Console.WriteLine("Nothing to be printed."); } } #endregion } /// <summary> /// Girlfriend information from xml file. /// </summary> [DataContract(Name = "GirlFriend", Namespace = "")] public class GirlFriend { #region properties [DataMember(Name = "Name", Order = 1)] public string Name { get; set; } [DataMember(Name = "Location", Order = 2)] public string Location { get; set; } #endregion } }
這裡需要注意幾點:
1、Student類前被標記了DataContract Attribute,其Name值要和xml文件的根節點相對應。Student類中每個屬性前被標記了DataMember Attribute,其Name值要和每個節點的名稱相對應。
2、由於GirlFriend節點下有子節點,所以需要新建類GirlFriend,用於儲存GirlFriend下的節點,其標記方式和Student類相似。
3、DataMember Attribute中有個屬性叫Order,該屬性代表所對應節點在xml文件中出現的順序,Order=1即代表該節點是在當前深度中的第一個節點,依次類推。
接下來新增類DeserializeXml類,實現反序列化xml文件的具體操作,細節如下:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace DeserializeXml
{
public class DeserializeXml
{
#region constructor
public DeserializeXml(string filePath)
{
FilePath = filePath;
}
#endregion
#region properties
public string FilePath
{
get;
set;
}
#endregion
#region public methods
public void DeserializeFromXml()
{
try
{
FileStream fs = new FileStream(FilePath,FileMode.Open);
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(fs, XmlDictionaryReaderQuotas.Max);
DataContractSerializer ser = new DataContractSerializer(typeof(Student));
Student student = (Student)ser.ReadObject(reader, true);
student.PrintInfo();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
#endregion
}
最後在Program類中進行簡單呼叫即可(最後為專案結構圖)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DeserializeXml
{
class Program
{
static void Main(string[] args)
{
DeserializeXml deserializeXml = new DeserializeXml("../../Student.xml");
deserializeXml.DeserializeFromXml();
Console.ReadKey();
}
}
}