CodeGym /Các khóa học /C# SELF /Làm việc với XmlSerializer...

Làm việc với XmlSerializer để serialize sang XML

C# SELF
Mức độ, Bài học
Có sẵn

1. Giới thiệu

XML — viết tắt của eXtensible Markup Language. Hãy tưởng tượng một JSON cực kỳ nghiêm túc và nhiều lời, luôn lặp đi lặp lại «tôi có cấu trúc, tin tôi đi!». XML là định dạng văn bản, trong đó dữ liệu được đóng trong các thẻ:

<Player>
  <Name>Aragorn</Name>
  <Health>100</Health>
</Player>

Tại sao chúng ta vẫn serialize đối tượng sang XML ngày nay?

  • XML vẫn được dùng rộng rãi trong tích hợp giữa các hệ thống lớn (thường là hệ thống legacy), nơi cần không chỉ cấu trúc mà còn validation theo các schema chặt chẽ (XSD).
  • XML thường dùng trong cấu hình doanh nghiệp (ví dụ, App.config và Web.config trong các phiên bản .NET cũ).
  • XML phù hợp cho các tình huống cần "self-describing" dữ liệu, khi cấu trúc tự giải thích là quan trọng.

Chuyện thú vị: XML được thiết kế để càng "mở rộng" và có thể validate càng tốt càng tốt; chính vì vậy mới có tên như vậy. Bạn có thể kiểm tra nó theo schema — điều mà JSON không có "out of the box".

XmlSerializer: nhân vật chính

Trong .NET, lớp System.Xml.Serialization.XmlSerializer chịu trách nhiệm serialize đối tượng sang XML.

  • Nó biến các public properties và fields của đối tượng thành phần tử XML, và ngược lại: từ XML khôi phục lại object.
  • Chỉ làm việc với các kiểu và thành viên public.
  • Không serialize private fields và properties — chỉ cái public thôi!
  • Đòi hỏi class để serialize phải có constructor không tham số (parameterless constructor).

Lưu ý: Nếu class của bạn không thỏa những yêu cầu này, XmlSerializer sẽ không thể làm việc với nó — sẽ ném exception khi serialize hoặc deserialize.

2. Ví dụ đơn giản — serialize object sang XML

Hãy xem cách serialize class yêu thích của chúng ta Player sang XML.

Bước 1. Mô tả class

public class Player
{
    public string Name { get; set; }
    public int Health { get; set; }
    public bool IsAlive { get; set; }

    // Quan trọng: cần constructor public không tham số!
    public Player() { }

    // Tùy chọn: để tiện
    public Player(string name, int health, bool isAlive)
    {
        Name = name;
        Health = health;
        IsAlive = isAlive;
    }
}

Bước 2. Serialize vào file

using System.Xml.Serialization;

Player aragorn = new Player("Aragorn", 100, true);

// 1. Tạo serializer cho kiểu Player
XmlSerializer serializer = new XmlSerializer(typeof(Player));

// 2. Mở file để ghi (sẽ tạo nếu chưa tồn tại)
using FileStream fs = new FileStream("player.xml", FileMode.Create);

// 3. Serialize object ra XML
serializer.Serialize(fs, aragorn);

Kết quả (player.xml):

<?xml version="1.0"?>
<Player xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Name>Aragorn</Name>
  <Health>100</Health>
  <IsAlive>true</IsAlive>
</Player>

Sơ đồ trực quan của quá trình đơn giản nhất


Đối tượng trong bộ nhớ  --->  XmlSerializer.Serialize()  --->  File XML trên đĩa

3. Deserialization — "hồi sinh" object từ XML

Khi cần đọc object đã serialize trước đó, quá trình là ngược lại:

using FileStream fs = new FileStream("player.xml", FileMode.Open);
XmlSerializer serializer = new XmlSerializer(typeof(Player));
Player player = (Player)serializer.Deserialize(fs);

Console.WriteLine($"Tên: {player.Name}, Sức khỏe: {player.Health}, Còn sống: {player.IsAlive}");

Kết quả chương trình sẽ in: Tên: Aragorn, Sức khỏe: 100, Còn sống: True

4. Serialize thành chuỗi — không chỉ vào file

Serialize thành chuỗi

Không phải lúc nào cũng muốn ghi vào file. Đôi khi cần gửi XML như một chuỗi qua mạng hoặc hiển thị trên màn hình.

using System.IO;
using System.Xml.Serialization;

Player player = new Player("Frodo", 42, true);

XmlSerializer serializer = new XmlSerializer(typeof(Player));
StringWriter stringWriter = new StringWriter();
serializer.Serialize(stringWriter, player);

string xmlString = stringWriter.ToString();
Console.WriteLine(xmlString); // Toàn bộ chuỗi XML — trên màn hình!

Deserialization từ chuỗi

Tương tự bạn có thể deserialize object không từ file mà từ chuỗi:

string xml = "<Player Name=\"Frodo\"><HP>42</HP></Player>";
XmlSerializer serializer = new XmlSerializer(typeof(Player));

using StringReader stringReader = new StringReader(xml);
Player frodo = (Player)serializer.Deserialize(stringReader);
Console.WriteLine(frodo.Name); // Frodo

5. Tuỳ biến XML: attribute để điều khiển cấu trúc

Đôi khi hành vi mặc định không phù hợp. XML có thể quá verbose hoặc tên thẻ không khớp yêu cầu. Lúc này các attribute "ma thuật" sẽ chỉ rõ cho serializer cách biểu diễn các member của class.

Mấy cái hữu dụng nhất:

  • [XmlElement]
    — đổi tên element (thẻ).
  • [XmlAttribute]
    — biến field/property thành attribute trong XML, không phải element.
  • [XmlIgnore]
    — loại bỏ property khỏi quá trình serialization.
  • [XmlArray]
    và
    [XmlArrayItem]
    — điều khiển cách đóng gói collection.

Ví dụ sử dụng:

public class Player
{
    [XmlAttribute]
    public string Name { get; set; }
    [XmlElement("HP")]
    public int Health { get; set; }
    [XmlIgnore]
    public bool IsTempSessionPlayer { get; set; }
}

XML kết quả:

<Player Name="Aragorn">
  <HP>100</HP>
</Player>

Bảng các attribute chính để serialize

Attribute Ảnh hưởng Ví dụ sử dụng
[XmlAttribute]
Biến property thành attribute của XML
<Player Name="Aragorn">...</Player>
[XmlElement]
Đổi tên thẻ (element)
<HP>100</HP>
thay vì
<Health>100</Health>
[XmlIgnore]
Loại bỏ hoàn toàn property khỏi serialization —
[XmlArray]
Đổi tên "bao bọc" cho collection
<Heroes> ... </Heroes>
[XmlArrayItem]
Đổi tên phần tử trong collection
<Hero>...</Hero>

Ví dụ serialize collection phức tạp:

public class GameWorld
{
    [XmlArray("Heroes")]
    [XmlArrayItem("Hero")]
    public List<Player> Players { get; set; } = new List<Player>();
}

XML:

<GameWorld>
  <Heroes>
    <Hero Name="Legolas">
      <HP>90</HP>
    </Hero>
    <!-- ... -->
  </Heroes>
</GameWorld>

Chi tiết hơn về tuỳ chỉnh XML mình sẽ đề cập ở các bài sau nhé! :P

2
Nhiệm vụ
C# SELF, mức độ, bài học
Đã khóa
Serialization và deserialization danh sách object
Serialization và deserialization danh sách object
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION