Cách chuyển đổi object thành xml

Tại sao chúng ta cần convert các đối tượng thành XML và XML thành đối tượng

–          Để chuyển các đối tượng thông qua Internet (hiện tại thì người ta hay sử dụng JSON vì đặc điểm gọn nhẹ và dễ đọc hiểu của nó hơn XML tuy nhiên trong các ứng dụng doanh nghiệp thì XML vẫn được sử dụng thường xuyên)

–          Để ghi vào file

–          Sử dụng trong các service phức tạp

Quá trình convert từ XML thành đối tượng và ngược lại được gọi là serialization và deserialization hay còn gọi là quá trình tuần tự hóa (Serialization là một quá trình để chuyển đổi một cấu trúc dữ liệu hoặc đối tượng thành một định dạng có thể lưu trữ được (ví dụ như trong một file, bộ nhớ, hoặc vận chuyển thông qua mạng), sau đó nó có thể được phục hồi để trở lại trạng thái ban đầu trong một môi trường khác thông qua quá trình deserialization) , đây là một chức tính năng quan trọng trong các ứng dụng đặc biệt là trong các ứng dụng có sự giao tiếp với các ứng dụng khác thông qua việc gửi và nhận dữ liệu

Trong .NET thì sử dụng namsespace System.Xml.Serialization để có thể chuyển đổi từ XML thành object

Các bạn tham khảo đoạn code

public static string GetXMLFromObject(object o) {

try {

     XmlSerializer serializer = new XmlSerializer(o.GetType());

     StringWriter sw = new StringWriter();

     XmlTextWriter tw = new XmlTextWriter(sw);

     serializer.Serialize(tw, o);

     return sw.ToString();

   } catch (Exception ex) {

//Handle Exception Code

} finally {

     sw.close();

     tw.close();

   }

}

 

public static Object ObjectToXML(string XmlOfAnObject, Type ObjectType) {

StringReader StrReader = new StringReader(XmlOfAnObject);

XmlSerializer serializer = new XmlSerializer(ObjectType);

XmlTextReader XmlReader = new XmlTextReader(StrReader);

try {

   Object AnObject = serializer.Deserialize(XmlReader);

   return AnObject;

} catch (Exception exp) {

   //Handle Exception Code

} finally {

   XmlReader.Close();

   StrReader.Close();

}

}

Ví dụ:

Public class Person {

Public string FirstName;

Public string LastName;

}

<Person >

<FirstName></FirstName>

<LastName></LastName>

</Person >

Bây giờ thử với class phức tạp hơn nhé

Public class Person {

Public string FirstName;

Public string LastName;

Public Address Address;

Public List<Friend> Friends;

}

Public class Address {

Public string Home;

}

Public class Friend{

Public string Name;

}

Khi chuyển qua XML có dạng sau

 

<Person >

<FirstName></FirstName>

<LastName></LastName>

<Address>

<Home></Home>

</Address>

<Friends>

<Friend>

<Name></Name>

</Friend>

…………………………

</Friends>

</Person >

Các bạn lưu ý là chỉ các thuộc tính khai báo là public thì mới được chuyển đổi thành các thẻ XML còn các thuộc tính protected hay private thì không.

Trong .NET thì có hỗ trợ thêm Attributes dùng để quy định cho việc serialization/deserialization. Đối với 2 ví dụ trên ta không khai báo Attributes nên khi convert thì thẻ XML sinh ra sẽ trùng với tên property. Ta có thể thay đổi tên thẻ sinh ra như ví dụ dưới

[XmlRoot(“Nguoi”)] //Thẻ root của XML sinh ra sẽ có tên là Nguoi

Public class Person {

[XmlElement(“Ho”)]

Public string FirstName; //với thuộc tính FirstName thì sinh ra thẻ XMl là Ho

 

[XmlElement(“Ten”)]

Public string LastName; //với thuộc tính LastNamethì sinh ra thẻ XMl là Ten

[XmlElement(“DiaChi”)]

Public Address address; //với thuộc tính address sinh ra thẻ XMl là DiaChi

 

[XmlArray(“DanhSachBanBe”)]

[XmlArrayItem(“Ban”)]

Public List<Friend> Friends;

}

Chuỗi XML sinh ra

<Nguoi >

<Ho></Ho>

<Ten></Ten>

<DiaChi>

<SoNha></SoNha>

</DiaChi>

<DanhSachBanBe>

<Ban></Ban>

………………………..

</DanhSachBanBe>

</Nguoi >

Các attributes mà .NET hỗ trợ hay được sử dụng

–          XmlRoot: quy định đây là root của thẻ XML

–          XmlElement: tham khảo ví dụ trên

–          XmlArray: tham khảo ví dụ trên

–          XmlArrayItem: tham khảo ví dụ trên

–          IgnoreXml: bỏ qua thuộc tính này không serialize hay deserialize

TIPS: Một số tips hay được sử dụng khi chuyển đổi xml thành object và ngược lại

–          Đối với trường dữ liệu kiểu bool khi chuyển đổi thì ta thường muốn cho giá trị là 0 hoặc 1 tuy nhiên với các hàm serialize của .NET thì lại chuyển thành true và false. Ta giải quyết cách này bằng việc bổ sung thêm thuộc tính cho đối tượng và ignore trường kiểu bool như ví dụ dưới

[XmlIgnore]

public bool MyValue { get; set; }

 

[XmlElement(“MyValue”)]

public string MyValueSerialize

{

get { return this.MyValue ? “1” : “0”; }

set { this.MyValue = XmlConvert.ToBoolean(value); }

}

–          Tương tự ta có thể áp dụng với kiểu DateTime

public class SomeClass

{

[XmlIgnore]

public DateTime SomeDate { get; set; }

 

[XmlElement(“SomeDate”)]

public string SomeDateString

{

       get { return this.SomeDate.ToString(“yyyy-MM-dd HH:mm:ss”); }

       set { this.SomeDate = DateTime.Parse(value); }

   }

}

–          Ngoài cách thêm thuộc tính thì các bạn có thể custom lại phần attribute của XML để có thể sinh ra thẻ cho đúng tuy nhiên mình thấy cách này hơi phức tạp nên không ghi trong bài nhé :3

–          Nếu bạn muốn sinh ra XML có thẻ XML có thêm thuộc tính thì nó thể sử dụng attributes XmlAttribute.

Public class Person {

[XmlAttribute]

Public string FirstName;

[XmlAttribute]

Public string LastName;

}

 

<Person FirstName=”” LastName =””></Person>

Thế nếu bạn muốn có đoạn text trong 1 element XML rồi lại có 1 element con thì sao. Khi đó bạn sử dụng XmlText

Public class Person {

[XmlText]

Public string FirstName;

[XmlElement]

Public string LastName;

}

 

<Person >

Lorem Ipsum is simply dummy text of the printing and typesetting industry.

<LastName></LastName>

</Person>

 

Đôi khi bạn lại muốn bỏ qua thẻ cha trong danh sách như ví dụ sau

public class Car

{

[XmlArray(“Passengers “)]

[XmlArrayItem(“Passenger”)]

public List<Passenger> Passengers {get; set;}

}

Mặc định thì chuỗi XML convert có dạng

<Car>

<Passengers>

   <Passenger>…</Passenger>

   <Passenger>…</Passenger>

</Passengers>

</Car>

Tuy nhiên bạn lại muốn thành

<Car>

   <Passenger>…</Passenger>

   <Passenger>…</Passenger>

</Car>

Thì đơn giản bạn chỉ cần để thành như sau

public class Car

{

[XmlElement(“Passenger”)]

public List<Passenger> Passengers {get; set;}

}

Nâng cao:

Đối với class kế thừa thì bạn bắt buộc phải sử dụng XmlArrayItem nếu không khi runtime thì code sẽ báo lỗi ngay :3 Ngoài ra thì phải sử dụng thêm Type như ví dụ dưới nhé

public class Group{

[XmlArrayItem(Type = typeof(Employee)),

XmlArrayItem(Type = typeof(Manager))]

public Employee[] Employees;

}

public class Employee{

public string Name;

}

public class Manager:Employee{

public int Level;

}

 

<Group>

<Employees>

   <Employee>

        <Name>Haley</Name>

   </Employee>

   <Employee xsi:type = “Manager”>

       <Name>Ann</Name>

       <Level>3</Level>

   <Employee>

</Employees >

</Group>

 

Đấy là các mẹo mình hay sử dụng đối với chuỗi XML; nếu có cái nào hay thì mình sẽ cập nhật vào cho các bạn tham khảo :3

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s