Serialization trong .NET
Serialization là mt quá trình chuyn đối tượng (object) sang mt hình
thc khác, để s dng khi lưu tr hoc chuyn d liu qua mng. Bài viết
này đề cp đến vic chuyn đối tượng sang dng XML.
XMLSerializer
.Net Framework cung cp các lp trong namespace System.XML.Serialization cho công vic
chuyn đổi này, trong đó lp XMLSerializer có vai trò quan trng. Mi th hin (instance) ca
lp này được to ra cho mi đối tượng cn chuyn. Nó cha các thông s ánh x để chuyn
thun hoc chuyn ngược gia đối tượng và d liu XML. Lp XMLSerializer có 2 phương thc
quan trng:
public void Serialize(Stream, object);
public object Deserialize(Stream);
Chúng ta có th s dng lp XMLSerializer như sau:
XMLSerializer serializer = new XMLSerializer(typeof(OrderedItem));
OrderedItem order = new OrderedItem();
...
//chuyn thun
XMLWriter writer = new XMLTextWriter(fs, new UTF8Encoding());
serializer.Serialize(writer, order);
//chuyn ngược
fs = new FileStream(ten_file, FileMode.Open);
XMLReader reader = new XMLTextReader(fs);
i = (OrderedItem) serializer.Deserialize(reader);
Mc định XMLSerializer s chuyn tt c các trường (field) public, các thuc tính (Property)
read/write và các giá tr khác null tr thành element vi tagname là tên thuc tính. Tt c các
element này được đặt trong lp element cha, vi tagname là tên lp. Ví d lp Person được trình
bày như dưới đây:
public class Person
{
public string Name = "Ten";
public int Age = 33;
private string Address = "HCM";
public string Sex = null;
public Person() { }
}
s được chuyn thành d liu XML:
<?XML version="1.0"?>
<Person XMLns:xsd="http://www.w3.org/2001/XMLSchema"
XMLns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>Ten</Name>
<Age>33</Age>
</Person>
Address không được chuyn vì nó là thuc tính private, và Sex cũng không có trong d liu
XML vì có giá tr null.
XMLSerializer có đầy đủ các chc năng để thc hin vic chuyn các đối tượng sang d liu
XML và ngược li. Sau đây, chúng ta s kho sát các khai báo cn thiết để chuyn các thuc tính
ca mt đối tượng sang d liu XML.
Chuyn các đối tượng
Nếu bn mun chuyn lp Person thành element vi tagname là Employee thay vì Person, bn
định nghĩa nó thông qua thuc tính XMLRoot:
[XMLRoot("Employee")]
public class Person
{...}
Nếu mun chuyn thuc tính Name thành element có TagName là PersonName, bn định nghĩa
nó thông qua XMLElement:
[XMLElement("PersonName")]
public string Name = "Ten";
// tương t thuc tính Age thành element PersonAge
[XMLAttribute("PersonAge")]
public int Age = 33;
Nếu không mun chuyn mt thuc tính dng public sang d liu XML, ta dùng XMLIgnore:
[XMLIgnore()]
public string Sex = "Nam";
Nếu các thuc tính có kiu là mt lp, các thành phn public ca lp được chuyn như đã định
nghĩa, và element tương ng ca lp s có tagname được định nghĩa trong XMLElement.
Lp Person được ch định bi:
[XMLElement("Supervisor")]
public Person Supervisor = null;
s được chuyn thành d liu XML như sau:
<Supervisor>
<PersonName>Ten</PersonName>
...
</Supervisor>
XMLIgnore có th giúp chúng ta chuyn hoc không chuyn sang XML mt trường hoc thuc
tính tùy thuc vào giá tr ca nó.
Để thc hin vic này, chúng ta thêm mt thuc tính mi vào lp vi tên trùng vi thuc tính
cng thêm t Specified sau đó. Ví d, chúng ta không mun chuyn thuc tính Age ca lp
Person, chúng ta thc hin như sau:
[XMLAttribute("PersonAge")]
public int Age = 33;
[XMLIgnore()]
public bool AgeSpecified = false;
Nếu AgeSpecified có giá tr là true, Age s được chuyn. Khi làm vic trên XMLSerializer tôi
rt thích đặc đim này vì nó giúp chúng ta bt tt vic chuyn theo giá tr.
Chuyn mng, danh sách,...
phn trên chúng ta đã ln lượt xem xét các khai báo XML để chuyn các đối tượng đơn, trong
phn này chúng ta s kho sát các khai báo cho các đối tượng tp hp (Collection).
Tương t như phn trên, chúng ta cũng phi chuyn các đối tượng dng mng vào thành mt
element.
[XMLArray("Agents")]
[XMLArrayItem("Agent", typeof(Person))]
public ArrayList Agents = null;
Kết qu khi chuyn s là:
<Employee>
<PersonName>Ten</PersonName>
<Agents>
<Agent>
<PersonName>Ten</PersonName>
</Agent>
</Agents>
</Employee>
ví d trên, các phn t có kiu là Person, đều được chuyn thành các element Agent. Nếu
mun thêm các kiu khác vào danh sách, chúng ta thêm các khai báo XMLArayItem tương ng
tiếp sau khai báo cho Person.
Nếu mun tt c các phn t trong danh sách đều có tagname ging nhau, chúng ta cn khai báo
XMLArrayItem vi mt tham s là ElementName (b qua kiu d liu).
Kết qu chúng ta có tp tin d liu XML như sau:
<Employee >
<PersonName>Name</PersonName>
<Agents>
<Agent xsi:type="Person">
<PersonName>Ten</PersonName>
</Agent>
<Agent xsi:type="Person1" />
</Agents>
</Employee>
Thuc tính xsi:type được thêm vào cho các element ca ArrayList để giúp vic chuyn ngược
d liu XML này sang đối tượng.
Trên đây tôi đã trình bày sơ lược v XMLSerializer. Nếu làm vic vi đối tượng này, bn s phát
hin nhiu điu đặc bit hơn na và hy vng bn s thích thú. .NET Framework cũng cho phép
bn ly các khai báo cho các lp để chuyn thông qua viết lnh. Nếu bn đã tng s dng
namespace System.Reflection trong .NET, hay reflection trong Java, chc là s cm thy thích
thú vi đặc đim này.
XMLSerializer có mt hn chế khi d án có s lượng lp quá ln. Khi đó, vic to th hin cho
hàng trăm lp có kh năng làm chm h thng. Tuy XMLSerializer cho phép bn khai báo để
ch tìm kiếm các đối tượng trong mt s lp cho trước, nhưng nó khá chm. Theo kinh nghim
ca tôi khi làm vic trên d án ln, bn ch nên to mt th hin ca XMLSerializer cho mi lp
và dùng nó xuyên sut toàn b ng dng thì vn đề tc độ thc thi s được gii quyết.