Đọc ghi dữ liệu xml trong C#

Đọc ghi dữ liệu xml trong C#

Trong một số trường hợp, việc lưu trữ giữ liệu vào các file XML là giải pháp tốt nhất, chúng thường được sử dụng để lưu trữ các thiết đặt hiển thị hoặc một số thông tin không cần bảo mật. Tương tự như với file text, tuy nhiên nó được tổ chức theo một cấu trúc dữ liệu và dễ dàng truy vấn sử lý hơn file thông thường. Bài viết sau đây mình sẽ chia sẻ với bạn cách để thêm, xóa, sửa dữ liệu XML (CRUD XML in C#) trong ngôn ngữ lập trình C#.

Cấu trúc tệp dữ liệu XML

Đầu tiên bạn cần tạo ra một cấu trúc dữ liệu XML.

Một cấu trúc dữ liệu XML mẫu

Trong cấu trúc mình tạo bạn có thể thấy, <Students> chính là tag thể hiện bảng học sinh, tag <Student> chứa từng record  học sinh với ID kèm theo, và 2 thuộc tính của record đó là Name và Age. Cấu trúc tệp này mô tả như một bảng trong CSDL thông thường. Bạn phải tồn tại ít nhất một dòng dữ liệu để mô tả cấu trúc của nó.

Thiết kế giao diện và import thư viện xử lý XML trong C#

Trong phần thiết kế này mình sử dụng những control cơ bản như textbox, button, và listview để hiển thị dữ liệu. Thiết kế như hình sau.

Giao diện thao tác XML cơ bản

Giao diện thao tác XML cơ bản

Tiếp theo mình sẽ import thư viện sử lý XML đó là using System.Xml.Linq;.

Bây giờ mình sẽ đi qua từng chức năng thao tác với XML trong C#.

Đọc dữ liệu từ XML và hiển thị trên ListView trong C#

Đầu tiền chúng ta sẽ khai báo một biến lưu đường dẫn đến tệp file xml cần xử lý. mình khai báo như sau:

 private string path = "....TestData.xml";

mình sử dụng “…. ” là vì tệp xml này đang nằm ở ngoài thư mục gốc. Nếu debug nó sẽ không tìm thấy file này trong thư mục Debug nên bạn phải ra ngoài 2 lần (mục debug nằm trong bin/debug).

Bây giờ mình sẽ tạo một hàm để load dữ liệu như sau.

private void loaddata()
 {
   try
     {
       listView1.Items.Clear();
       DataSet dataSet = new DataSet();
       dataSet.ReadXml(path);
       DataTable dt = new DataTable();
       dt = dataSet.Tables["Student"];
       int i = 0;
       foreach (DataRow dr in dt.Rows)
       {
         listView1.Items.Add(dr["ID"].ToString());
         listView1.Items[i].SubItems.Add(dr["Name"].ToString());
         listView1.Items[i].SubItems.Add(dr["Age"].ToString());
         i++;
       }
     }
     catch (Exception)
     {

     }
 }

Hàm trên mình kết hợp tải dữ liệu và đọc vào Listview. Trong hàm trên mình sử dụng dataset để đọc dữ liệu từ XML qua tệp được khai báo trong biến Path. Mình tạo thêm một datatable để lấy dữ liệu từ item Student. Cuối cùng mình sử dụng một hàm Foreach đọc dữ liệu từ datatable và đưa vào các Items của Listview. Lưu ý là mình có sử dụng hàm bẫy lỗi Try...Catch... để hạn chế lỗi khi tệp XML bị vấn đề. Sau khi viết xong hàm bạn có thể gọi hàm này từ form load và test thử.

Thêm dữ liệu từ XML trong C#

Khi thêm dữ liệu, bạn phải chú ý thêm ID làm sao đó để nó khác với các ID còn lại. Thông thường mình sẽ sử dụng thời gian, chuyển đổi thành các chuỗi nối với nhau tạo ra một dãy số khác nhau theo thời gian để làm ID. Đoạn code sau mình viết trong nút thêm.

 string day = DateTime.Now.Day.ToString();
 string month = DateTime.Now.Month.ToString();
 string year = DateTime.Now.Year.ToString();
 string hour = DateTime.Now.Hour.ToString();
 string minute = DateTime.Now.Minute.ToString();
 string second = DateTime.Now.Second.ToString();
 long id = long.Parse(day + month + year + hour + minute + second);
 try
   {
      XDocument testXML = XDocument.Load(path);
      XElement newStudent = new XElement("Student", 
      new XElement("Name", textBox1.Text), 
      new XElement("Age",textBox2.Text));

      var lastStudent = testXML.Descendants("Student").Last();
      long newID = Convert.ToInt64(lastStudent.Attribute("ID").Value);
      newStudent.SetAttributeValue("ID", id);

      testXML.Element("Students").Add(newStudent);
      testXML.Save(path);
      loaddata();
    }
 catch (Exception err)
 {
    MessageBox.Show(err.Message);
 }

Trong đoạn code thêm trên mình sử dụng kết hợp một chuỗi, ngày+tháng+năm+giờ+phút+giây để làm ID. Nếu bạn thấy dữ liệu được ghi vào nhiều hơn có thể sử dụng thêm mili giây. Tất cả mình sẽ đưa về một biến kiểu long có tên là ID.

Tiếp theo bạn khai báo một document có tên là testXML hay cái gì tùy và đưa đường dẫn file XML vào, sau đó mình sẽ tạo ra một đối tượng Element có tên là newStudent sau đó truyền vào các thuộc tính Element con như Name và Age. Mình sẽ sử dụng SetAttributeValue để chèn ID vào id trong tag Student. Cuối cùng là mình add cái Element newStudent vào bảng Students và save lại theo đường dẫn path. Khúc cuối mình có gọi lại hàm loaddata để lấy dữ liệu lên lại hiển thị trên listview. Mình cũng sẽ để toàn bộ mã này trong hàm Try...Catch... để theo dõi lỗi phát sinh.

Kết quả khi thêm vào dữ liệu XML

Kết quả khi thêm vào dữ liệu XML (ID có ngày 6/6/2017 – là ngày mình viết bài này)

Xóa dữ liệu từ XML trong C#

Trước khi muốn xóa dữ liệu bạn phải biết được ID cần xóa của dòng dữ liệu đó. Trong một số phần mềm được thiết kế tinh tế, người ta không show ra loại ID này vì nó không có nghĩa với người dùng. Người dùng cũng không muốn gõ một đoạn số dài để xóa, vì thế nên mình cần có một thao tác đặt biệt để lấy ID của trường muốn xóa trước. Điều này cũng được áp dụng cho việc sửa.

Trong bài này mình sử dụng Listview nên mình sẽ sử dụng sự kiện SelectedIndexChanged của nó và viết một đoạn code như sau.

 foreach (ListViewItem item in listView1.SelectedItems)
 {
   textBox1.Text = item.SubItems[1].Text;
   textBox2.Text = item.SubItems[2].Text;
   textBox3.Text = item.SubItems[0].Text;
 }

Đoạn tên có thể dễ hiểu là mình sẽ lặp những Item trong cái dòng được selected và lưu vào biến item biến này là một mảng chứa nhiều trường được đánh số từ 0 trở lên. Bạn có thể nhấn vào listview và chọn edit colum để chỉnh sửa các trường phù hợp.

Theo thứ tự load data như trên thì ở cột đầu mình sẽ cho hiển thị ID. Bạn cũng có thể ẩn trường này bằng cách cho width về 0. Cột tiếp theo sẽ hiển thị tên và cột cuối cùng sẽ hiển thị tuổi.

Các trường này mình sẽ lấy dữ liệu lên các textbox phục vụ cho mục đích sửa sau này luôn ID bạn có thể dùng một biến để lưu lại hoặc cho nó show ra luôn cho dễ kiểm soát.

Sau khi đã lấy được ID lên textbox, mình tiến hành viết code cho nút xóa để xóa dữ liệu xác định.

 try
 {
   if (textBox3.Text != "1112201518597")
   {
     XDocument testXML = XDocument.Load(path);
     XElement cStudent = testXML.Descendants("Student").Where(c => c.Attribute("ID").Value.Equals(textBox3.Text)).FirstOrDefault();
     cStudent.Remove();
     testXML.Save(path);
     loaddata();
    }
    else
    {
       MessageBox.Show("vui lòng không xóa trường này !");
    }
 }
 catch (Exception err)
 {
    MessageBox.Show(err.Message);
 }

Trong đoạn này mình có sử dụng một hàm if để kiểm tra và không cho xóa dòng có ID đầu tiên. Dĩ nhiên bạn có nhiều cách khác như kiểm tra nếu dữ liệu chỉ có một dòng thì không cho xóa,… nhưng ở đây mình làm nhanh. Tiếp theo như thông thường mình sẽ tạo ra một document có tên testXML và load đường dẫn file XML lên, sau đó mình sẽ sử dụng một câu truy vấn Linq để lấy ra một element có ID như yêu cầu, sau đó là sử dụng phương thức Remove() để xóa element này đi và cuối cùng là save nó lại và load dữ liệu thay đổi lên. Mình vẫn sử dụng hàm try…catch để bắt lỗi xảy ra.

Kết quả sau khi xóa dữ liệu XML

Kết quả sau khi xóa dữ liệu XML

Sửa dữ liệu từ XML trong C#

Cũng tương tự như xóa, mình cũng cần lấy ID và các nội dung cũ lên để người dùng sửa. Tuy nhiên mình sẽ không cần viết lại nữa thì ở trên mình đã viết rồi. bây giờ mình sẽ code cho nút sửa như sau:

 try
 {
    XDocument testXML = XDocument.Load(path);
    XElement cStudent = testXML.Descendants("Student").Where(c => c.Attribute("ID").Value.Equals(textBox3.Text)).FirstOrDefault();
    cStudent.Element("Name").Value = textBox1.Text;
    cStudent.Element("Age").Value = textBox2.Text;
    testXML.Save(path);
    loaddata();
 }
 catch (Exception err)
 {
   MessageBox.Show(err.Message);
 }

Các bước trên làm tương tự như phần xóa. Sau khi truy vấn được dòng cần sửa thì bạn làm các bước để set lại giá trị cho 2 trường là Name và Age, cuối cùng là lưu lại và load dữ liệu thay đổi lên. Và mình cũng không quên bước bỏ try…catch để xem hiện tượng lỗi gì phát sinh nhé.

Kết quả sửa dữ liệu XML mình lên được 25 tuổi :)

Kết quả sửa dữ liệu XML mình lên được 25 tuổi 🙂

Bên trên là bài hướng dẫn cơ bản thao tác với dữ liệu XML, nếu bạn thấy hay đừng quên bấm Like và Share nhé.

Chúc bạn thành công !