-- C#

C# ile XML Serialization

Merhabalar,

Bu makalede lafı hiç uzatmadan serileştirme(Serialization) yöntemlerinden biri olan XML Serialization’ı inceleyeceğiz.

Serialization Nedir?

Yazılım uygulamalarında bazı verileri yazılımın çalıştığı sisteme kaydetmemiz ya da ağ üzerinden farklı bir kaynağa iletmemiz gerektiği durumlar olabilir. Eğer yerel sisteme veri kaydetmemiz gerekirse bu göreceli olarak kolaydır. Çünkü herhangi bir ek protokol ya da sınırlandırma minimum düzeydedir. Herhangi bir dosya formatı şeklinde kendi sisteminize kaydedebilirsiniz. Yüksek ihtimal bunun için gerekli Framework sınıfları da kullandığınız platform içerisinde hazırdır. Ancak yazılımınız ile ağ üzerinden ya da internet üzerinden farklı bir noktaya veri aktarımı yapmak istediğinizde burada platformlar ve protokoller arası uyuşmazlıklar söz konusu olabilir. Örneğin sizin geliştirdiğiniz yazılım .NET ile geliştirildiyse ve ama karşıya gönderilen veriyi alıp işleyecek farklı bir yazılım varsa ve bu yazılım .NET harici bir platformla geliştirildiyse, burada tercih etmeniz gereken yöntem mecburi olarak ortak bir serileştirme yöntemi olmalıdır. Ya da yazılımınızın yerel bir ağ da olması ile internet üzerinden veriyi aktarması gibi durumlar arasında da serileştirme yöntemlerinde farklı mecburiyetler sonucunda seçimler yapılması gerekmektedir.

Serileştirme Yöntemleri

Çok özetle serileştirmeyi anlatmaya çalıştım. Daha detayları spesifik olarak anlatacağım.

XML Serialization Nedir?

XML Serialization işleminden önce, eğer XML’in ne olduğunu bilmeyen arkadaşlar var ise şuraya tıklayarak temel olarak XML yapısını ve neden gerekli olduğunu öğrenmelidir.

XML yapısı yazılımda bir standart olarak kabul edilmektedir. Bu standardın neden gerekli olduğunu ise özetle belirteyim. .NET ile bir uygulama geliştirdiniz ve veritabanınızdaki bir veriyi dışarıdan erişmek isteyen kullanıcılara açmak istiyorsunuz. Örneğin; bir eticaret sitesi kendi ürünlerini ve temel bazı bilgileri satış ve pazarlama politikaları gereği farklı eticaret sistemleri ya da müşterilerinin yazılımına aktarmasına izin vermektedir. Bunun için tüm işletim sistemlerinde(platformlar) ve tüm programlama diliyle tüm Framework’ler için geçerli ve aynı standartları uygulaması beklenecektir. İşte bu tür platformlar arası veri aktarımı ya da transferi için XML(ve günümüzde JSON) formatı yıllardır tercih edilmektedir. Bu nedenle yazılımcılar çoğunlukla XML ile haşır neşir olmuştur ve olacaktır da…

Tüm bu nedenlerden dolayı geliştirdiğiniz yazılımda ister doğrudan veritabanından isterseniz kendi yazılımınızdan XML çıktı almanız gerekecektir. Bu XML çıktıyı yazılım ile üretme ve depolama ile farklı bir kaynağa aktarma işine XML Serialization diyoruz.

Peki nerelerde kullanılabilir ve özellikleri nelerdir?

  • XML insan gözüyle okunabilen bir metin dosyasıdır. Bu şekilde değerlendirilebilir alanlarda kullanılabilir. Ancak güvenlik seviyesi yüksek bilgiler XML ile iletilmemeli ya da depolanmamalıdır.
  • Bir web yazılımından veri aktarmak için gerekli olan HTTP’yi destekler. Bu nedenle web projelerinde sıklıkla XML tabanlı web servis yapıları kullanılır. Örnek XML Web Servis eğitimlerim için tıklayın.
  • Binary Serialization kadar hızlı değildir ve Binary S.’den daha çok yer kaplar. Ancak Binary Serialization HTTP’yi desteklemez. Bu nedenle XML S. ile Binary S. kıyaslanmamalıdır.
  • XML sık kullanılan veri kaynaklarındandır. Bu nedenle platformlar arası sorunlardan kurtulmak için yüksek veri güvenliği gerektirmeyen ve küçük veritabanı ihtiyaçlarında bir veritabanı olarak da tercih edilebilir.

Uygulamamızı geliştirmeye başlayabiliriz. Öncelikle gerekli namespace’leri ekleyelim;

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

Örneğe başlayabiliriz;

Temel Kullanım

Serialization işlemi;

static void Serialize(List<string> data)
{
    FileStream fs = new FileStream("domains.xml", FileMode.Create);
    XmlSerializer serializer = new XmlSerializer(typeof(List<string>));
    serializer.Serialize(fs, data);
    fs.Close();
}

Deserialization işlemi;

static List<string> Deserialize()
{
    FileStream fs = new FileStream("domains.xml", FileMode.Open);
    XmlSerializer xs = new XmlSerializer(typeof(List<string>));
    List<string> liste = (List<string>)xs.Deserialize(fs);
    fs.Close();
    return liste;
}

Serialization kullanımı;

Bu örneğimizde serileştirmek için bir string listesi kullanıyoruz.

List<string> datas = new List<string>();
datas.Add("http://www.cihanozhan.com");
datas.Add("http://www.dijibil.com");
datas.Add("http://www.cofly.co");

Serialize(datas);

Not : Eğer Serialize() metodunu biraz değiştirip parametre olarak liste almak yerine string almasını sağlarsanız ve içerisindeki XmlSerializer(typeof(….)) kısmında string verirseniz doğrudan tekil bir string de gönderilebilir olacaktır.

Deserialization kullanımı;

List<string> liste = Deserialize();
foreach (string l in liste)
{
    Console.WriteLine(l);
}

Deserialize işlemi de başarıyla çalışacaktır. Ancak bu metodu dışarıdan XML path ve dosya adı alacak şekilde düzenlemeniz daha doğru olacaktır. En basit haliyle anlatılmıştır.

XML Serialization işleminin temel prensiplerini anlatmaya çalıştım. Temel kısımlarda herhangi bir zorluk yoktur. Şimdi bir sınıf ile XML oluşturma, bu sınıfı manipüle ederek XML çıktıyı değiştirmek gibi işlemlere bakalım. İşin uzmanlık kısmı burada başlıyor diyebiliriz.

Sınıflar İle XML Serialization;

XML çıktı üretmek için kullanacağımız ilk sınıf aşağıdaki gibidir;

[Serializable]
public class Kullanici
{
    public int KullaniciId { get; set; }
    public string KullaniciAd { get; set; }
    public string Email { get; set; }
    public string AttrAlan { get; set; }

    public Kullanici(int kullaniciId, string kullaniciAd, string email)
    {
        this.KullaniciId = kullaniciId;
        this.KullaniciAd = kullaniciAd;
        this.Email = email;
        this.AttrAlan = "AttributeXDD";
    }

    public Kullanici() { }
}

Bu sınıf gördüğünüz üzere basit bir C# sınıfıdır. Tek farkı, standart olarak sınıf üzerinde kullanmamız gereken [Serializable] niteliğidir. Ve XML serileştirme işleminde önemli bir konu da serileştirilmek istenen sınıfın içerisinde bir boş yapıcı metot(constructor) olması gerekliliğidir. Eğer boş yapıcı metot olmazsa zaten hata iletisini gözünüze gözünüze sokacaktır editörümüz. 🙂

Yukarıdaki sınıfı gerekli XML nitelikleriyle süsleyip sonrasında açıklayayım.

[Serializable]
[XmlType(TypeName = "User")] // Kullanıcı sınıfının User adında bir XML kök dizini olarak çıktı üretmesini sağlar. Bunu kullanmazsanız XML'in kök dizini Kullanici olacaktır.
public class Kullanici
{
    [XmlElement(ElementName = "UserId", Type = typeof(int))] // XML çıktı içinde üretilecek element'in adını UserId olarak üretmesini sağlar.
    public int KullaniciId { get; set; }
    public string KullaniciAd { get; set; } // KullaniciAd adında bir element üretecektir.
    public string Email { get; set; } // Email adında bir element üretecektir.
    [XmlAttribute]
    public string AttrAlan { get; set; } // Üzerindeki XmlAttribute niteliği sayesinde bu özellik XML içerisinde bir nitelik olarak üretilecektir. Eğer kullanılmazsa varsayılan olarak element üretilir.

    public Kullanici(int kullaniciId, string kullaniciAd, string email)
    {
        this.KullaniciId = kullaniciId;
        this.KullaniciAd = kullaniciAd;
        this.Email = email;
        this.AttrAlan = "AttributeXDD";
    }

    public Kullanici() { }
}

Yukarıdaki sınıfı tekil bir nesne oluşturup serileştirmek için kullanacağız. Şimdi yeni bir sınıf daha oluşturalım. Bu oluşturacağımız sınıfı da metoda bir liste olarak göndermek için kullanacağız.

[Serializable]
//[XmlType(TypeName = "Kullanici")]
public class User
{
    [XmlAttribute(AttributeName = "UserId")]
    //[XmlAttribute]
    public int KullaniciId { get; set; }

    [XmlAttribute(AttributeName = "Username")]
    //[XmlAttribute]
    public string KullaniciAd { get; set; }

    [XmlAttribute(AttributeName = "Email")]
    //[XmlAttribute]
    public string Email { get; set; }

    public User(int kullaniciId, string kullaniciAd, string email)
    {
        this.KullaniciId = kullaniciId;
        this.KullaniciAd = kullaniciAd;
        this.Email = email;
        //this.AttrAlan = "AttributeXDD";
    }

    public User() { }
}

Şimdi bu sınıfları serileştirmek için gerekli iki serileştirme metodu yazalım. Biri sadece Kullanici sınıfı alırken, diğeri User sınıfının listesini alacak birer metot.

/// <summary>
/// Kullanici sınıfı alan Serialize metodu.
/// </summary>
/// <param name="kullanici"></param>
static void Serialize(Kullanici kullanici)
{
    FileStream fs = new FileStream("Kullanici.xml", FileMode.Create);
    XmlSerializer xs = new XmlSerializer(typeof(Kullanici));
    xs.Serialize(fs, kullanici);
    fs.Close();
}

/// <summary>
/// User listesi alan Serialize metodu.
/// </summary>
/// <param name="kullanicilar"></param>
static void Serialize(List<User> kullanicilar)
{
    FileStream fs = new FileStream("Kullanicilar.xml", FileMode.Create);
    XmlSerializer xs = new XmlSerializer(typeof(List<User>));
    xs.Serialize(fs, kullanicilar);
    fs.Close();
}

Örneklerin kullanımı;

Tekil sınıf oluşturarak serileştirelim;

Serialize(new Kullanici() { KullaniciId = 3, KullaniciAd = "CihanOzhan", Email = "co@cihan.co" });
// ya da 
Serialize(new Kullanici(kullaniciId : 3, kullaniciAd : "CihanOzhan", email : "co@cihan.co"));

Çoğul bir liste oluşturup serileştirelim;

// User listesi oluşturuyoruz.
List<User> Kullanicilar = new List<User>();
Kullanicilar.Add(new User(1, "CihanOzhan", "cihan@ozhan.com"));
Kullanicilar.Add(new User(3, "RecepIvedik", "recep@ivedik.com"));
Kullanicilar.Add(new User(7, "AliKundilli", "ali@kundilli.com"));

// User listesini Serialize metoduna gönderiyoruz.
Serialize(Kullanicilar);

XML işlemlerinde çok fazla detay vardır. Örneğin karmaşık bir XML yapısı sunan bir web servis hizmetini .NET sınıflarına dönüştürebilmek için ciddi bir uğraş gerektirecektir. Bu işlem de tamamen XML Serilalization konusuna girmektedir.

İyi çalışmalar.
Cihan Özhan

Yorumla

Yorum