Cumartesi, Haziran 11, 2011

ASP .Net Linq ile XML kullanımı (Linq to XML)

.Net kullanmaya başladığımdan beri en çok beğendiğim özelliklerden biri hiç kuşkusuz Linq. Gerçekten bir çok konuda işleri bir hayli kolaylaştırmakta. Linq sayesinde diziler,sql, yazının konusu olan XML ve hatta google üzerinde bile işlem yapabiliyoruz. Daha önce linq ile nasıl sql işlemleri(sorguları) yapıldığından bahsetmiştim. Bu sefer de XML ile ilgili işlemlerin nasıl yapıldığından bahsedeceğim.

Aslından Linq kullanmadan da .Net'te XML işlemleri yapmak gayet kolay. Bir çok hazır sınıfın yanında XML şeması oluşturup daha sonra bunu sınıf yapısına çevirerek nesne olarak da işlem yapmak mümkün.

XML dosyamızın yapısı aşağıdaki şekilde
<?xml version="1.0" encoding="utf-8"?>
<kullanicilar>
      <kullanici id="1">
        <ad>A</ad>
        <soyad>B</soyad>
      </kullanici>
      <kullanici id="2">
        <ad>C</ad>
        <soyad>D</soyad>
      </kullanici>
      <kullanici id="5">
        <ad>E</ad>
        <soyad>F</soyad>
      </kullanici>
      <kullanici id="8">
        <ad>G</ad>
        <soyad>H</soyad>
      </kullanici>
    </kullanicilar>

Veri Okuma
Veri okumak için XDocument sınıfından yararlanıyoruz. Bu sınıftan bir nesne türetip yine aynı sınıfın static "Load()" metodu yardımıyla dosyamızı açıyoruz ve üzerinde Linq ile işlem yapılabilir hale getiriyoruz.
protected void Page_Load(object sender, EventArgs e)
{
    XDocument doc = XDocument.Load(Server.MapPath("~/XMLFile.xml"));
    if (doc != null)
    {
        IEnumerable<XElement> myUsers = from t0 in doc.Element("kullanicilar").Elements("kullanici")
                                        select t0;

        foreach (XElement user in myUsers)
        {
            Response.Write(user.Element("ad").Value + " " + user.Element("soyad").Value + "<br />");
        }
    }
}

Dikkat çekmek istediğim diğer metodlar "Element()" ve "Elements()". İlki tek bir "XElement" nesnesi döndürürken ikincisi "IENumrable" döndürür. Bundan dolayıda myUser değişkeni "IENumrable" tipinde bir değişken olur. İşin güzel tarafı Anonymous Type şeklinde veriler oluşturmakta mümkün. Bu sayede XML dosyasından çektiğimiz verileri direk olarak GridView,Dataview yada Repeater'a DatatSource olarak aktarmak mümkün



protected void Page_Load(object sender, EventArgs e)
{
    XDocument doc = XDocument.Load(Server.MapPath("~/XMLFile.xml"));
    if (doc != null)
    {
        var myUsers = from t0 in doc.Element("kullanicilar").Elements("kullanici")
                      where t0.Element("ad").Value == "A" || t0.Element("ad").Value == "C"
                      select new 
                      { 
                        Ad = t0.Element("ad").Value,
                        Soyad = t0.Element("soyad").Value,
                      };

        grdUserList.DataSource = myUsers;
        grdUserList.DataBind();
    }
}

Veri Ekleme

protected void Page_Load(object sender, EventArgs e)
{
    XDocument doc = XDocument.Load(Server.MapPath("~/XMLFile.xml"));
    if (doc != null)
    {
        XElement myElement = doc.Element("kullanicilar");
        XElement addedElement = new XElement(new XElement("kullanici", new XElement("ad", "Esat"), new XElement("soyad", "Arslan")));
        addedElement.SetAttributeValue("id", "5");
        myElement.Add(addedElement);
        doc.Save(Server.MapPath("~/XMLFile.xml"));
        
        var myUsers = from t0 in doc.Element("kullanicilar").Elements("kullanici")
                      select new
                      {
                          Ad = t0.Element("ad").Value,
                          Soyad = t0.Element("soyad").Value,
                      };
        grdUserList.DataSource = myUsers;
        grdUserList.DataBind();
    }
}

Veri ekleme için ilk önce parent node'u seçtik. Daha sonra XElement sınıfından oluşturduğumuz nesneyi "Add()" metodunu kullanarak dosyaya ekledik ve kaydettik.

Veri Güncelleme

protected void Page_Load(object sender, EventArgs e)
{
    XDocument doc = XDocument.Load(Server.MapPath("~/XMLFile.xml"));
    if (doc != null)
    {
        XElement myElement = (from t0 in doc.Element("kullanicilar").Elements("kullanici")
                             where t0.Attribute("id").Value == "5"
                             select t0).SingleOrDefault();

        if (myElement != null)
        {
            myElement.SetAttributeValue("id", "100");
            doc.Save(Server.MapPath("~/XMLFile.xml"));
        }

        var myUsers = from t0 in doc.Element("kullanicilar").Elements("kullanici")
                      select new
                      {
                          ID = t0.Attribute("id").Value,
                          Ad = t0.Element("ad").Value,
                          Soyad = t0.Element("soyad").Value,
                      };
        grdUserList.DataSource = myUsers;
        grdUserList.DataBind();
    }
}

Linq cümlesi kullanarak "id" değeri "5" olan kaydı çektik, xml yapısında ID değerleri nitelik(attribute) olarak girildiği için "SetAttributeValue()" metodu ile değerini "100" olarak değiştirip dosyayı kaydettik.

Kolay gelsin...

6 yorum:

memo dedi ki...

Hocam merhaba şöyle bir sorunum var hiç bir yerde çözümü bulamadım bana yardımcı olabilir misiniz?XML'le Full Flash yaptığım siteye yönetim paneli yapmaya çalışıyorum , ASP.Net ten LINQ TO xml yöntemiyle aşağıdaki kodlarla XML e kayıt ekleme yapıyorum ancak beşinci elementte ifadesi eklemem gerekiyor aşağıdaki gibi yaptığımda XML' e < karakterlerinin yerine "'<'" > karakterinin yerine de "'&bt;' ifadesini yani bu karakterlerin kodlarını çıkarıyor ben < ve > karakterlerini XML;'e olduğu gibi nasıl kaydedebilirim, bu durumu nasıl düzeltebilirim yardımcı olabilir misiniz? Çok teşekkürler şimdiden...


XElement xml = new XElement("photo",

new XElement("thumbnail", TextBox1.Text),
new XElement("filename", TextBox2.Text),
new XElement("baslik1", TextBox3.Text),
new XElement("baslik2", TextBox4.Text),
new XElement("description",""),
new XElement("link", TextBox6.Text),
new XElement("fiyat1", TextBox7.Text),
new XElement("indorani", TextBox8.Text));



XDocument doc = XDocument.Load(Server.MapPath("~/App_Data/satislar.xml"));

doc.Root.Add(xml);

doc.Save(Server.MapPath("~/App_Data/satislar.xml"));

Response.Write("kayıt eklendi");

Esat ARSLAN dedi ki...

Merhaba memo;

Kullanmaya çalıştığın karakterler XML için özel anlam ifade eden karakterler olduğu için direk olarak kullanmana izin verilmez. Her ne kadar XML dosyasına kod karşılığı kaydedilsede LinqToXML kullanarak okurken karakterler yine senin istediğin şekilde görünecektir.

Aşağıdaki linki incele istersen.
http://msdn.microsoft.com/en-us/library/ms171485.aspx

memo dedi ki...

Merhaba şöyle bir sorum olacak; sizin kullandığnız xml dosyasını örnek verecek olursak XMLFile.xml dosyasında
kullanicilar tagindan
kaç tane element olduğunu nasıl bulabiliriz yani o dosyanın lenght ini alma imkanımız var mı

Esat ARSLAN dedi ki...

Mesela yukarıdaki "Veri Okuma" örneğinden yola çıkarsak "myUser" değişkeni "kullanicilar" node'u içindeki "kullanici" node'larını temsil eder. myUser'ın "Count()" fonksiyonu yardımı ile de node sayısını öğrenebilirsin.

"myUsers.Count();" gibi.

Mesut dedi ki...

Root element is missing. hatası alıyorum. Neden olabilir?

Esat ARSLAN dedi ki...

XML deki node yapısı ile ilgili bir sorun olabilir.