Trong phần này chúng ta tìm hiểu cách thức C# hỗ trợ chuẩn XML. Trong C# có cung cấp một không gian tên System.Xml bao gồm nhiều tiện ích để ta có thể làm việc với các tài liệu XML. Do giới hạn về thời gian, tài liệu nên trong phần này chúng em chỉ đi sâu vào một số vấn đề chính.
IV.1. Tạo một tài liệu XML
Giả sử ta muốn tạo một tài liệu XML có cấu trúc nh sau:
Chơng trình sau sẽ tạo ra file ‘c:\car.xml’
using System; using System.IO; using System.Xml; using System.Text; class CarDomWriter { CarDomWriter(Stream outStr){
XmlDocument doc = new XmlDocument(); XmlDeclaration decl =
doc.CreateXmlDeclaration("1.0", "UTF-8", null); doc.AppendChild(decl);
XmlNode root = CreateCarNode(doc); doc.AppendChild(root);
new XmlTextWriter(outStr, new UTF8Encoding()); writer.Formatting = Formatting.Indented; doc.WriteTo(writer); writer.Flush(); writer.Close(); }
XmlNode CreateCarNode(XmlDocument doc){ XmlElement car = doc.CreateElement("Car"); car.SetAttribute("VIN","123");
XmlNode model = CreateModelNode(doc); car.AppendChild(model);
XmlNode miles = CreateMilesNode(doc); car.AppendChild(miles);
return car; }
XmlNode CreateModelNode(XmlDocument doc){ XmlElement model = doc.CreateElement("Model"); XmlElement year = doc.CreateElement("Year"); year.InnerText = "1998"; model.AppendChild(year); XmlElement mfr = doc.CreateElement("Maker"); mfr.InnerText = "Honda"; model.AppendChild(mfr);
XmlElement make = doc.CreateElement("Make"); make.InnerText = "Civic";
model.AppendChild(make); return model;
}
XmlNode CreateMilesNode(XmlDocument doc){ XmlElement miles = doc.CreateElement("Mileage"); miles.SetAttribute("Units", "Miles");
miles.InnerText = "80000"; return miles;
}
public static void Main(){
FileStream outStr = new FileStream( "c:\\car.xml",FileMode.Create); try { new CarDomWriter(outStr); } finally { outStr.Close(); } } }///:~
Thao tác đầu tiên là tạo một đối tợng XmlDocument, sau đó ta lần lợt tạo ra các node và gắn chúng vào XmlDocument. Ta gắn một node vừa tạo bằng phơng thức XmlDocument.AppendChild(). Sau khi tạo khai báo ( coi nh một node và gắn vào
XmlDocument ), ta tạo node gốc là Car. Cứ tiếp tục quá trình tạo ra các node tiếp theo, nếu node nào đó có thuộc tính ta dùng phơng thức XmlElement.SetAttribute(). Sau khi hình thành đợc cấu trúc XML, ta tạo một đối tợng XmlTextWriter để có thể ghi lên luồng file ra FileStream.XmlDocument.WriteTo() nhận XmlTextWriter làm tham số, và ghi lên đó cấu trúc của tài liệu XML. Thao tác cuối cùng là đẩy dữ liệu ở bộ nhớ vào luồng file ra bằng việc gọi phơng thức XmlTextWriter.Close().
Xem kết quả bằng trình duyệt IE 6.0:
Hình 19 Kết quả chơng trình tạo tài liệu trên IE 6.0
IV.2. Duyệt tài liệu XML
Giả sử sau khi đã tạo ra tài liệu XML nh trên, ta muốn duyệt tài liệu đó. Trong C# tồn tại hai kiểu duyệt đó là duyệt theo luồng và duyệt theo cây. Duyệt theo luồng là duyệt mà ở đó ta mở một luồng dữ liệu vào và duyệt luồng dữ liệu này một cách liên tục không qua bộ đệm và không cần tạo ra đối tợng cho mỗi node. Cách duyệt này tăng hiệu năng của quá trình duyệt và ứng dụng cho các tài liệu XML cỡ lớn. Cách duyệt thứ hai là duyệt theo cây, ở đây toàn bộ cấu trúc của file đợc tải vào bộ nhớ sau đó ta tiến hành duyệt theo từng node. Quá trình duyệt sử dụng thuật toán đệ qui. Trong ví dụ dới đây ta sử dụng cách duyệt theo cây:
Chơng trình sau sẽ duyệt file ‘c:\car.xml’
using System; using System.IO;
using System.Xml; class CarReader {
CarReader(string fileName){
XmlDocument doc = new XmlDocument(); doc.Load(fileName);
WriteInfo(doc); }
void WriteInfo(XmlNode node){
Console.WriteLine("Current node is of type {0}", node.NodeType); if (node.NodeType == XmlNodeType.Element) { Console.WriteLine("<{0}>", node.Name); foreach(XmlAttribute att in node.Attributes){ Console.WriteLine("[{0}] = {1}", att.Name, att.Value); } } if (node.NodeType == XmlNodeType.Text) { Console.WriteLine("Text = " + node.Value); }
foreach(XmlNode child in node.ChildNodes){ WriteInfo(child);
} }
public static void Main(){ new CarReader("c:\\car.xml"); }
}///:~
IV.3. Quá trình Serializing
Không gian tên System.Xml.Serialization cung cấp cho chúng ta khả năng chuyển đổi từ t liệu XML sang các dạng cấu trúc dữ liệu khác trên cùng một miền (Deserializing) và chuyển từ tập các đối tợng có thể tạo ra một t liệu XML chuẩn (Serializing).
Quá trình serializing chỉ chuyển hoá các thuộc tính public của một đối tợng (hoặc là trờng public của một đối tợng –tuy nhiên ít dùng). Bên cạnh đó quá trình chuyển hoá yêu cầu lớp của đối tợng là lớp public và hàm khởi tạo không có tham số truyền vào. Điều này để tránh xung đột giữa trạng thái trong của một đối tợng.
Ta xét ví dụ trên, ta tạo một đối tợng từ lớp Car, với các thuộc tính public và ứng với mỗi thuộc tính của đối tợng nếu ta muốn sau quá trình chuyển hoá nó đợc chuyển thành thuộc tính của thành phần của XML thì ta thêm [XmlAttribute] vào trớc đoạn code đó. Sau khi tạo đối tợng rồi, ta tiến hành chuyển hoá bằng cách tạo ra một XmlSerializer và dùng phơng thức XmlSerializer.Serialize() với tham số là đối tợng c và một XmlTextWriter để ghi ra dòng file. Sau đây là code:
using System;
using System.Xml.Serialization; using System.IO;
using System.Text; using System.Xml; public class Car { public Car(){ }
string vin; [XmlAttribute] public string VIN{ get { return vin;} set { vin = value;} }
Model model;
public Model Model{ get { return model;} set { model = value;} }
Mileage miles;
public Mileage Mileage{ get { return miles;} set { miles = value;} }
public static void Main(){ Car c = new Car(); c.VIN = "123";
c.Model = new Model(1998, "Honda", "Civic"); c.Mileage = new Mileage("Miles", 80000);
XmlSerializer xs = new XmlSerializer(typeof(Car)); FileStream outStr=new FileStream(“c:\\ser_car.xml”, FileMode.Create);
XmlTextWriter writer=new XmlTextWriter(outStr, new UTF8Encoding()); writer.Formatting=Formatting.Indented; xs.Serialize(writer, c); writer.Flush(); writer.Close(); } }
public class Model { public Model(){ }
public Model(int yr, string mfr, string make){ this.yr = yr;
this.mfr = mfr; this.make = make; }
int yr;
public int Year{ get { return yr;} set { yr = value;}
}
string mfr;
[XmlElement("Maker")] public string Maker{ get { return mfr;} set { mfr = value;} }
string make;
public string Make{ get { return make;} set { make = value;} }
}
public class Mileage { string units;
[XmlAttribute("Units")] public string Units{ get { return units;} set { units = value;} }
int val; [XmlText]
public int Quantity{ get { return val;} set { val = value;} }
public Mileage(){ }
public Mileage(string units, int val){ this.units = units;
this.val = val; }
}
IV.4. Quá trình Deserializing
Đây là quá trình ngợc lại so với quá trình Serializing. Quá trình chuyển hoá sẽ chuyển một t liệu XML thành một đối tợng cùng kiểu.
Ví dụ sau ,ta chuyển tài liệu XML ‘c:\car.xml’ thành đối tợng car tơng ứng với điều kiện ta phải khai báo lớp Car trong chơng trình (nh ví dụ phần trớc).Kết quả đợc kết xuất ra console:
using System; using System.IO;
using System.Xml.Serialization; public class CarFromFile { public static void Main(){
XmlSerializer xs = new XmlSerializer(typeof(Car)); FileStream str =
new FileStream("c:\\car.xml", FileMode.Open); Car c = (Car) xs.Deserialize(str);
str.Close();
Console.WriteLine("{0} {1} {2}, {3} {4}", c.Model.Year, c.Model.Maker, c.Model.Make, c.Mileage.Quantity, c.Mileage.Units);
} }///:~
Kết quả nh sau:
Phần V: Lập trình mạng trong C#
Cụng nghệ Web cú tớnh thương mại cao đối với bất kỳ nền cụng nghiệp nào mà giỏ trị nhận được từ luồng chảy của thụng tin, cú thể núi đối với tất cả cỏc ngành cụng nghiệp. Khi mà cỏc mỏy desktop là những nhà quản lý sự kế thừa, thỡ cỏc khớa cạnh lập trỡnh được phỏt triển theo 2 hướng chớnh: một là trờn server và hai là trờn cỏc thiết bị post_dessktop như handhelds, tablets, và phones. Cụng việc lập trỡnh trờn cỏc thiết bị non_desktop khụng bị phụ thuộc vào cỏc nền tảng cơ bản khỏc như lập trỡnh “enterprise” hay “mobile”. Hơn thế nữa, cỏc thuộc tớnh, quản lý bộ nhớ và tiến trỡnh, cỏc kiến trỳc cơ sỡ dữ liệu của ADO.NET và sức mạnh của XML đó được bổ sung thờm vào sự hổ trợ hướng đối tượng một cỏch hoàn toàn trong ngụn ngữ lập trỡnh C#.