[DOTNETVN] Sử dụng XML Trong Xamarin

Tải file đính kèm: XmlDemo

Trong bài viết này mình muốn giới thiệu cũng như hướng dẫn cơ bản cho các bạn về cách lưu trữ dữ cũng như thao tác đọc dữ liệu liệu đơn giản sử dụng XML File trong lập trình mobile với Xamarin.

XML là loại file dữ liệu phổ biến nhất và được đại đa số lập trình viên sử dụng trong dự án của họ để lưu trữ dữ liệu nhỏ gọn cung như tận dụng khả năng portable cao của file XML.

Trong một số ứng dụng nhỏ, đơn giản và đặc biệt không đòi hỏi lưu trữ quá nhiều dữ liệu thì giải pháp mà đa số các bạn lập trình viên cũng như các công ty sử dụng trong dự án là lưu data dưới dạng File có thể là File Text đơn giản hoặc là sử dụng File XML.

Trong phạm vi bài viết này mình sẽ trình bài hết sức đơn giản từ cách đọc/ghi dữ liệu từ File XML sao cho thuận tiện và dễ dàng nhất cũng như cách nạp dữ liệu vào danh sách và hiển thị ra màn hình để các bạn nhanh chóng làm quen và nắm bắt.

1. Ví dụ mẫu:

Mình sẽ xây dựng một ví dụ mẫu hết sức đơn giản là lưu trữ dữ liệu thông tin khách hàng bằng File XML.

Lưu ý: Soure code được đính kèm trên đầu bài viết các bạn có thể download về tham khảo nhé heart

2. Xây dựng cấu trúc dữ liệu khách hàng đơn giản:

Trong ví dụ này mình sẽ tạo một lớp có tên là Customer chứa các thông tin cơ bản như ID, Name, Email và Phone cơ bản thì sẽ như sau:

class Customer
{
    public int ID { get; set; }
    public string Name { get; set; }
}

3. Xây dựng giao diện hiển thị danh sách khách hàng:

Giao diện đơn giản chỉ có một listview để hiện thị danh sách khách hàng và một form để nhập tên khách hàng mà thôi cool

Code giao diện được đặt trong file MainPage.xaml nhé

Giao diện sau khi chạy sẽ như sau:

4. Tạo File XmlHelper.cs:

OK công việc tiếp theo là cần viết code để thao tác với XML nhỉ wink, ở đây chúng ta sẽ có 2 hàm cơ bản là đọc và ghi mình sẽ đặt lần lược là "Serialize (chuyển object customer thành file XML)" và "Deserialize (đọc XML data vào object Customer)" nhé.

public class XmlHelper
{      
    public static void SerializeObject<T>(T data)
    {
        var stringwriter = new System.IO.StringWriter();
        var serializer = new XmlSerializer(data.GetType());
        serializer.Serialize(stringwriter, data);
        var xml = stringwriter.ToString();
        DependencyService.Get<IXmlApi>().Write(xml);
    }

    public static T DeserializeFromString<T>()
    {         
        try
        {
            var xmlString = DependencyService.Get<IXmlApi>().ReadXmlString();
            var stringReader = new System.IO.StringReader(xmlString);
            var serializer = new XmlSerializer(typeof(T));
            return (T)serializer.Deserialize(stringReader);
        }
        catch
        {
            return default(T);
        }
    }
}

Mình nói sơ qua về đoạn code phía trên một chút nhé, các bạn có thấy gì lạ ?, đó là Dependency tại sao mình lại dùng Dependency ở đây. Như các bạn đã biết thì Xamarin là một công nghệ cho phép phát triển ứng dụng di động đa nền tảng nhưng không có nghĩa là các bạn có thể thao tác trực tiếp với Api của từng loại hệ điều hành như Android, IOS chỉ với một vài dòng code. Trong ví dụ trên mình cần đọc và ghi từ một đường dẫn trong điện thoại nhưng trong portable class không có cách nào đọc được đường dẫn một cách chính xác bởi vì mỗi loại hệ điều hành có cấu trúc đường dẫn khác nhau, do đó kỹ thuật Dependency được sử dụng để giải quyết vấn đề này.

Xamarin đã cung cấp sẵn một đối tượng có tên là DependencyService để giúp lập trình viên có thể thao tác dễ dàng khi dùng kỹ thuật Dependency nhé nên đừng quá lo lắng hay sợ phức tạp.

5. Đọc/Ghi File XML dùng Dependency:

Công việc tiếp theo cần làm là tạo một lớp Interface trong Project Portable chứa 2 Method như bên dưới

public interface IXmlApi
{
    void Write(string data);
    string ReadXmlString();
}

và dĩ nhiên khi tạo xong Interface thì chúng ta cần tạo một lớp để Implement 2 Method đọc và ghi XML, mình sẽ tạo một lớp có tên là XmlApi và đặt trong Project Android như hình bên dưới

Bên trong code lúc này chúng ta sẽ Implement 2 Method đọc và ghi như sau:

[assembly: Dependency(typeof(XmlApi))]
namespace XmlDemo.Droid
{
    public class XmlApi:IXmlApi
    {
        private string GetFilePath()
        {
            const string fileName = "customers.xml";
            var dbPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData);
            var path = Path.Combine(dbPath, fileName);
            return path;
        }

        public void Write(string data)
        {
            string fileName = GetFilePath();
            if (File.Exists(fileName))
                File.Delete(fileName);
            File.WriteAllText(fileName, data);
        }


        public string ReadXmlString()
        {
            string fileName = GetFilePath();
            return File.ReadAllText(fileName);
        }
    }
}

Hàm GetFilePath dùng để lấy thông tin đường dẫn file trong android còn 2 hàm đọc và ghi mình không giải thích ở đây vì nó quá đơn giản để hiểu cheeky

Một điểm chú ý là dòng [assembly: Dependency(typeof(XmlApi))] các bạn cần đăng ký Dependency cho file XmlApi theo đúng cú pháp như đoạn tô đậm là được

OK xong hết rồi, bây giờ việc cuối cùng là quay lại Project Portable mở source code của file MainPage.xaml ra code

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MainPage : ContentPage
{
    public List<Customer> Customers { get; set; }
    public MainPage()
	{
		InitializeComponent();
        LoadData();
        buttonAdd.Clicked += ButtonAdd_Clicked;

    }

    private void LoadData()
    {
        Customers = XmlHelper.DeserializeFromString<List<Customer>>();
        if (Customers == null)
            Customers = new List<Customer>();

        CustomerList.ItemsSource = Customers;
    }

    private void ButtonAdd_Clicked(object sender, EventArgs e)
    {
        Customers.Add(new Customer { ID =new Random().Next(1000, 99999), Name = editorName.Text });
        XmlHelper.SerializeObject(Customers);
        LoadData();
    }
}

Trong đoạn code trên các bạn có thể thấy mình đã khai báo 1 biến với kiểu dữ liệu là List<Customer> để lưu trữ danh sách khách hàng và gán vào ItemSource của ListView song song đó có 1 hàm là LoadData dùng để load lại dữ liệu cho swiss replica watches ListView trong hàm này mình sẽ thực hiện thao tác đọc dữ liệu từ file Xml.

Để gọi hàm dùng dependency các bạn quay lại lớp XmlHelper sẽ nhìn thấy dòng

DependencyService.Get<IXmlApi>().Write(xml);

đây là cú pháp để gọi hàm dùng Dependecy trong Xamarin nhé, mình nghĩ cũng không cần giải thích gì thêm công việc của các bạn là ghi nhớ cú pháp thôi wink

Cuối cùng các bạn chạy ứng dụng và tự cảm nhận nhé, source code đã được đính kèm phía trên (chạy trên Visual Studio 2017)

Note: Trong bài viết này mình sử dụng cách thông thường để reload lại dữ liệu là gán lại ItemSource, mình sẽ dành thời gian để nói về một cách khác và cũng là cách mà các bạn cần phải nắm vững khi thao tác với XAML đó là mô hình MVVM và Data Binding

Thông tin bài viết