Makale Özeti

Xml dosyalarını veri kaynağı olarak kullanmamız için önce geçerli bir nedenimiz olmalı, öyle değil mi?

Makale

Xml Dosyalarını Veri Kaynağı Olarak Kullanmak

 

Xml dosyalarını veri kaynağı olarak kullanmamız için önce geçerli bir nedenimiz olmalı, öyle değil mi?

Veritabanından okunan bilgiye (dataset ile) bağlantısızken de erişebilmek,  serverda log tutmak, tutulan loglarda hızlı aramalar yapmak ve en önemlisi verimizi platform bağımsız olarak paylaşabilmek gibi kısaca birkaç neden sayabiliriz.

 

Veriler ile işlem yaparken ilk yaptığımız iş önce verilerimizi yazmaktır ki ; daha sonra üzerlerinde  değişiklik yapabilelim. Xml dosyasına elle yazmak için XmlWriter  sınıfını kullanacağız.

 

 Private Sub urunEkle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles urunEkle.Click

 

'Xml dosyamızı yaratıyoruz, dosya mevcutsa silip yenisini yaratır.

 

 Dim xmlYazici As New XmlTextWriter("xmlDosyam.xml", System.Text.Encoding.Unicode)

 

            'Xml dosyalarındaki girintili formatın elde edilmesi için

        xmlYazici.Formatting = Formatting.Indented

           

            'Dosyaya yazmaya başlayabiliriz.

        xmlYazici.WriteStartDocument()

 

            'Dosyaya yazacağımız veriyi formdan alalım.

            Dim girilenUrunKodu As String=TextBox1.Text

            Dim girilenUrunAdi  As String=TextBox2.Text

 

        'Bu xml dosyamızın (root) kök elementidir.

        xmlYazici.WriteStartElement("urunler", "")

        

                        xmlYazici.WriteStartElement("urun")

                        xmlYazici.WriteElementString("urunKodu", girilenUrunKodu)

                        xmlYazici.WriteElementString("urunAdi", girilenUrunAdi)

                        xmlYazici.WriteEndElement()

 

        xmlYazici.WriteEndElement()

        xmlYazici.WriteEndDocument()

 

        xmlYazici.Flush()

        xmlYazici.Close()

 

End Sub

 

 

 

Oluşacak xml dosyası görünümü:  Bu dosyadan makalenin devamında  “xmlDosyam.xml”  şeklinde bahsedeceğiz.

 

<?xml version="1.0" encoding="utf-16"?>

<urunler>

  <urun>

    <urunKodu>0001</urunKodu>

    <urunAdi>kalem</urunAdi>

  </urun>

</urunler>

 

Yukarıdaki kod metin kutularına girilen bilgileri yarattığı xml dosyasına kaydeder. Ama gerçek uygulamalarda bu pek işinize yaramayabilir.

sadece tek bir node yazmak için dosyayı silip yeniden yazmak pek akıllıca olmayacağı için döngü kullanarak blok haldeki verinizi

dosyaya yazabilrsiniz.

 

 Private Sub ButunUrunleriEkle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButunUrunleriEkle.Click

 

            Dim urunKoduDizi() As String= {"001","002","003","004","005"}

            Dim urunAdiDizi()  As String={"kalem","kitap","defter","silgi","kalemtras"}

 

 

 Dim xmlYazici As New XmlTextWriter("xmlDosyam.xml", System.Text.Encoding.Unicode)

 

 

        xmlYazici.Formatting = Formatting.Indented

           

        xmlYazici.WriteStartDocument()

 

 

        xmlYazici.WriteStartElement("urunler", "")

 

                        Kök düğümümüz oluştuktan sonra her bir ürün için yeni bir düğüm ve içine ikişer adet element ekleyelim.

                       

            For sayac As Integer=0 To urunKoduDizi.Length - 1

 

                          xmlYazici.WriteStartElement("urun")

                          xmlYazici.WriteElementString("urunKodu", urunKoduDizi(sayac))

                         xmlYazici.WriteElementString("urunAdi", urunAdiDizi(sayac))

                         xmlYazici.WriteEndElement()

              Next

 

        xmlYazici.WriteEndElement()

        xmlYazici.WriteEndDocument()

        xmlYazici.Flush()

        xmlYazici.Close()

End Sub

 

Bu kodun çıktısı olan dosya biçimi (“xmlDosyam.xml”) :

 

<?xml version="1.0" encoding="utf-16"?>

<urunler>

  <urun>

    <urunKodu>0001</urunKodu>

    <urunAdi>kalem</urunAdi>

  </urun>

  <urun>

    <urunKodu>0002</urunKodu>

    <urunAdi>kitap</urunAdi>

  </urun> 

  <urun>

    <urunKodu>0003</urunKodu>

    <urunAdi>defter</urunAdi>

  </urun>

  <urun>

    <urunKodu>0004</urunKodu>

    <urunAdi>silgi</urunAdi>

  </urun>

  <urun>

    <urunKodu>0005</urunKodu>

    <urunAdi>kalemtras</urunAdi>

  </urun>

</urunler>

 

Aynı kodu bir de döngü içinde yazdık ki kodların işlevlerini net olarak anlayalım.

Buraya kadar xml dosyamıza yazdık. İyi ama her defasında bu dosyayı silip yeniden yazıyoruz. Ya içinde önemli bir veri varsa ve ben onu kontrol edip

"Bilgi yoksa dsoyaya ekleyeyim, varsa işlem yapmadan çıkayım" diyorsanız okumaya devam edin.

 

Öncelikle mevcut dosya üzerinde hızlı bir arama yapıp kayıt dosyada yoksa içeriğini kaybetmeden dosyaya ekleme yapmalıyız.

 

Xml dosyasını okumanın (ki bu işlemi çoğunlukla search amaçlı kullanırız) bazı yöntemleri :

 

1-Dosyayı StreamReader ile açıp satır satır okumak ve satırlar içinden aranan bilgiyi metin olarak bulmak.

Yani xml dosyasına text dosya muamelesi yapmış oluyoruz ki bu durumda pek kullanışlı bir yöntem değil.

2-Dosyayı XmlTextReader ile açıp düğümleri tek tek okumak.Bu ilkine göre daha hızlıdır ancak arada gereksiz düğümler de okunur.Vakit kaybına yol açar.

3-XmlNodeReader kullanarak düğümlerde gezinerek arama yapmak.Ama bu yöntem de dosyada düğümlerde sırayla gezerek ilerler.

4-Xml dosyasını DataSet e atarak arama yapmak, dataSet üzerinde (dataRow kullanarak) ekleme yapmak ve iş bitince dosyayı yeni haliyle tekrar yaratmak.

Ama büyük dosyalarda dataSet e dönüştürmenin ve dosyayı yeniden yaratmanın da performans maliyeti olacaktır.

5-XmlNodeList kullanarak aradığınız bilginin tipindeki elementleri bellekte bir diziye atarak sadece bellekteki bu diziden arama yapabiliriz.

Yani bu son yöntemde belli bir ürün kodunu arıyorsak (örn:0001) xmlNodeList yalnızca <urunKodu> adlı elementlerin elementstring değerlerini okuyup bunları

nodelist te tutacaktır.

 

Bahsettiğimiz tüm bu yöntemleri birer kod örneği ile inceleyelim.

 

1-Xml Dosyasını StreamReader ile Okuma:

 

'Dosya işlemleri için bu isim uzayını eklemeyi unutmayalım.

Imports System.IO

 

Dim sr As StreamReader = New StreamReader("deneme.xml")

 

            Dim satir As String

            'Dosya sonuna kadar satır satır okumak için döngü oluşturuyoruz.

            While sr.Read()

                satir = sr.ReadLine()

 

                        If InStr(satir,"aradığım bilgi") Then

                       

                        Response.write("Data Dosyada Mevcut!")

                       

                        Exit while 'Aradığımız veriyi bulunca arama işlemine son veriyoruz.

              

            End While

           

                'Kod yazarken kullandığımız nesnelerle işimiz bittiğinde onları serbest bırakmayı unutmayalım.

                'Gerçi Garbage Collector var ama bu devirde kimseye güven olmuyor J.

                sr.Close()

 

2-Xml Dosyasını XmltextReader ile okuma:

Bu yöntem ile xml dosyasını forward-only yöntemiyle düğüm düğüm okur.

 

'Bu defa sadece Xml 'in kendi isim uzayına ihtiyacımız var.

Imports System.Xml

 

 

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

      

            'XmlReader tanımlayalım ve okuyacağımız dosyaya bağlayalım.

        Dim reader As New XmlTextReader(Server.MapPath("xmlDosyam.xml"))

 

        reader.MoveToFirstAttribute()

           

            'Aradığımız değeri belirtelim.

        Dim arananDeger As String = "000001"

 

        While reader.Read

           

            If reader.ReadString() = arananDeger Then

                Response.Write("Aranan veri dosyada bulundu'")

                Exit While

            End If

        End While

    End Sub

 

Yukarıdaki kodda ReadString() metodu ile element ya da text düğümlerimizin sadece içeriklerini metin olarak döndürüyoruz.

Burada da düğüm bazında basit bir aramayı görmüş olduk.

 

3-XmlNodeReader ile arama yapmak:

 

Imports System.Xml

 

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

 

 Dim arananDeger As String = "000001"

 Dim arananDeger2 As String = "kalem"

  Dim xmlDoc As New XmlDocument

        Dim xmlNoder As XmlNodeReader

        Dim urunkodum As String

 

        xmlDoc.Load(Server.MapPath("xmlDosyam.xml"))

       

 

While xmlNoder.Read

            ' Look for the user we need

            If xmlNoder.Name = "urunKodu" And xmlNoder.NodeType = XmlNodeType.Element Then

                urunkodum = xmlNoder.ReadString

 

                If urunkodu <> arananDeger Then xmlNoder.Skip()

'Aradığımız veri bu değilse direkt diğer node' a atlıyoruz.

 

            ElseIf xmlNoder.Name = "urunAdi" And xmlNoder.NodeType = XmlNodeType.Element Then

                If xmlNoder.ReadString() = arananDeger2 Then

 

                    Response.Write("BULUNDU")

                Else

 

                    xmlNoder.Skip()

                End If

            End If

 

        End While

 End Sub

 

Burada bir önceki kodumuzdan farklı olarak xmlNodeReader kullandık ve okuyacağımız dosyayı bağlama işlemini daha açık bir yöntemle yazdık

 ve döngü içine IF sorgularıyla element adını kontrol edip yalnızca belirli elementlerde arama yapmayı sağladık.

 

4-Xml dosyasında dataset kullanarak arama yapmak:

 

Imports System.Xml

 

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Dim ds As New DataSet

        ds.ReadXml(Server.MapPath("xmlDosyam.Xml"))

        Dim arananVeri As String = "000001"

        Dim dr As DataRow

        Dim dt As DataTable

        dt = CType(ds.Tables(0), DataTable)

 

        For Each dr In dt.Rows

            If dr("veriAranacakKolonAdi") = arananVeri Then

                Response.Write("Dosyada Bulundu!")

                Exit For

            End If

        Next

    End Sub

 

Yukarıdaki kodda öncelikle bir dataset yaratıp içine xml dosyasmızdaki verileri atıyoruz.Dataset içinde oluşacak datatable nesnesini alıyoruz.

Bu datatable yapısını gözümüzde canladırırsak: xml dosyasındaki <urunAdi>,<urunKodu> gibi elemenler burada sütun olarak karşımıza çıkacaktır ve

elementstring 'leri yani değerleri de satırları dolduracaktır.Aramayı da bu yapıya uygun şekilde yapıyoruz.

 

5-Xml dosyasında XmlNodeList ile arama yapmak:

 

İşte en seçtiğim kısma geldik. Buradaki yapı şimdiye kadar anlatılanlardan daha mantıklı ve hızlı görünüyor, bakalım.

Şimdi bir xml dosyasında arama yapan ve aradığı bilgiyi dosya sonuna kadar bulamazsa bu bilgiyi dosyaya (append) ekleyen kodumuzu inceleyelim.

 

Imports System.Xml

 

            Sub XmldeAraBulamzsan Ekle()

 

            Dim xmlDoc As New XmlDocument

        Dim xmlNoder As XmlNodeReader

            Dim urunkodum As String="000001"

            Dim urunAdim As String ="kalem"

     

            ' XML dosyasını açar içinde urunKodu nu arar..

 

            xmlDoc.Load("xmlDosyam.xml")

 

          

                'Burası önemli: Burada oluşturacağımız nodelist içine koyacağımız verilerin tipini(kolonunu) belirliyoruz.

                        'Yapısını yukarda belirttiğim dosyadan SADECE <urun> node' larından <urunKodu> elementlerinin listesini

                        'alıyoruz çünkü unique değerimiz bu.

                        'SQL select cümlesini andırdığı için bu ismi verdim.

                       

                Dim selectCumlesi As String = "//urun[urunKodu=" + urunKodum + "]"

                Dim xmlNodeListesi As XmlNodeList = xmlDoc.SelectNodes(selectCumlesi)

 

                If xmlNodeListesi.Count > 0 Then

                    'XML dosyasında aranan kayıt bulunduğunda kod buraya girer.

                Else

 

                    'Bulunamazsa veriyi append eder.

                    Dim root As XmlNode = xmlDoc.DocumentElement

                    Dim childNodeBas As XmlElement = xmlDoc.CreateElement("urun")

                    Dim childNode1 As XmlElement = xmlDoc.CreateElement("urunKodu")

                    Dim childNode2 As XmlElement = xmlDoc.CreateElement("urunAdi")

 

                    root.AppendChild(childNodeBas) '<urunler> kök düğümüne <urun> yavru düğümü eklenir.

 

                    '<urun> yavru düğümüne de urunKodu ve urunAdi düğümlerinin değerleri eklenir.

                    childNode1.InnerText = urunKodu

                    childNodeBas.AppendChild(childNode1)

 

                    childNode2.InnerText = urunAdi

                    childNodeBas.AppendChild(childNode2)

 

                    'Dosyanın son hali kaydedilir.

                    xmlDoc.Save("xmlDosyam.xml")

 

                End If

 

            Next

           

End Sub

 

Bu kodda asıl önemli olan nokta efektif bir nodelist oluşturmak için selectcumlesi adlı değişkeni iyi belirlemektir. Zira dosyada ne kadar hızlı bir arama yapacağımız bu cümleye bağlıdır. Bu cümleyi oluştururken referans olarak http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/1431789e-c545-4765-8c09-3057e07d3041.asp

sayfasını incelemenizi tavsiye ederim. Bu kodla dosyadaki <urunKodu> elementlerinin listesi

oluşturulur ve bunda arama yapılır. Son olarak bulunmazsa dosya sonuna eklenir. Eklerken tabii yeni düğümlerin hiyerarşisini dosyadakilerle aynı yapmak zorundayız yoksa bir sonraki arama kodunda son eklediklerimiz yapıya uymadıklarından bulunamayacaktır.

Dosyayı kaydediyoruz.

 

Xml dosyaları üzerinde yapabileceğimiz işlemlerin bazılarından (okuma, yazma, güncelleme ) kısaca bahsettik. Bir dahaki makalede görüşmek dileğiyle..