XLinq .NET Language Integrated Query for XML Data

XLinq .NET Language Integrated Query for XML Data XLinq .NET Language Integrated Query for XML DataXLinq .NET Language Integrated Query for XML Data XML Verileri için .NET ile Bütünle?ik Sorgulama   Giriş

XML günümüzde Word dokümanlarından, internetteki kullanımına, configurasyon dosyalarından veritabanlarına kadar geniş bir yelpazede çok başarılı bir şekilde kullanılmaktadır. XML heryerde olmasına rağmen yazılım geliştirme perspektifinden bakacak olursak, XML halen kullanması zor bir teknoloji olarak karşımıza çıkar. Ortalama bir programcıya XML ile çalışmanın nasıl olduğunu sorarsanız bir dolu şikayet ile karşılaşabilirisiniz. XML ile çalışmak için seçilebilecek API arabirimleri ya artık teknolojinin gerisinde kalmaya başlamış, ve DOM veya sadece XML merkezli XQuery veya XSLT gibi dillerde uzmanlaşma gerektirmektedir. LINQ projesinin bir parçası olan XLinq, bu sorunu çözmeyi amaçlamaktadır. XLinq .NET Framework’de bulunan son dil gelişmelerini kullanarak hafızada bulunan XML dokümanlarını işlemek için yazılmış modern bir APIdır. XLinq, hem DOM hem de XQuery / XPath fonksiyonalitesini diğer LINQ arabirimleri ile dengeli ve düzenli bir programlama deneyimi ile bir araya getirmeye çalışır.

Bu yazımızda, örnek bir VB XLinq projesi yaratıp, XLinq’in sunduğu teknolojilere bir giriş yapacağız. 

VB XLinq için örnek bir proje Başlangıç

Linq programlama ortamını kullanabilmek için, Microsoft’un sitesinde yayımladığı Language-Integrated Query Community Technology Preview May 2006 sayfasından Download butonuna tıklayarak LINQ Preview (May 2006).msi dosyasını bilgisayarınıza indirip kurun. C# ile programlama yapacaksanız, C# compiler’ını güncelleyeyim mi sorusuna evet diyin. Bu programı kurduğunuz zaman Visual Studio 2005’inizdeki VB ve C# derleyicileri yeni LINQ komutlarını algılayacak şekilde güncellenir, ve sisteminize LINQ ile ilgili örnekler, dokümanlar, ve bir çok egzersizler yüklenir. LINQ teknolojisi ile ilgileniyorsanız bu egzersizleri yapmanız, dokümanları okumanız size çok şey katacaktır. Sorularınızı her zaman karşılaştığınız sorunu net bir şekilde açıklayarak, ve kod örnekleri ile destekleyerek Microsoft’a sorabilirsiniz.

Gerekli kurulumları yaptıktan sonra, Visual Studio’nuzu açıp yeni bir proje yarattığınızda karşınıza LINQ ile ilgili yeni proje tipleri gelir. Aşağıdaki resimden de görebileceğiniz gibi Visual Basic Linq Console Application’u seçip, projenize bir isim verin. 

Önce bir DOM objesi ile XML dokümanı

 

   

      Lawnmower

      1

      148.95

   

 

 

Bu yazımızda tüm vereceğimiz örnekleri yukarıdaki örnek XML dokümanını temel alarak vereceğiz. Öncelikle XML DOM objesini kullanarak yukarıdaki XML dokümanını hafızada nasıl yaratırız ona bakalım. Tabii ki bir XmlDocument class’ına ihtiyacımız olacak, bu class’ın oluşturduğumuz bir objesinin CreateElement(), CreateAttribute(), Append, AppendChild gibi methodlarını çağırarak arzu ettiğimiz dokümana ulaşmamız mümkün.

 

Module Module1

    Sub Main()

        Dim PO As New XmlDocument()

        Dim purchaseOrder = PO.CreateElement("purchaseOrder")

        PO.AppendChild(purchaseOrder)

        Dim orderDate = PO.CreateAttribute("orderDate")

        orderDate.Value = "1999-10-20"

        purchaseOrder.Attributes.Append(orderDate)

        Dim items = PO.CreateElement("items")

        purchaseOrder.AppendChild(items)

        Dim item0 = PO.CreateElement("item")

        items.AppendChild(item0)

        Dim partNum0 = PO.CreateAttribute("partNum")

        partNum0.Value = "872-AA"

        item0.Attributes.Append(partNum0)

        Dim productName0 = PO.CreateElement("productName")

        productName0.AppendChild(PO.CreateTextNode("Lawnmower"))

        item0.AppendChild(productName0)

        Dim quantity0 = PO.CreateElement("quantity")

        quantity0.AppendChild(PO.CreateTextNode("1"))

        item0.AppendChild(quantity0)

        Dim price0 = PO.CreateElement("price")

        price0.AppendChild(PO.CreateTextNode("148.95"))

        item0.AppendChild(price0)        Console.WriteLine(PO.OuterXml)

        Console.ReadLine()

   End Sub

End Module

Yukarıdaki örnekte PO adında bir XML dokümanı yarattık, bu dokümana elementleri eklemek istiyorsak önce bu elementleri yaratıp sonra her element’i dokümana, veya içinde bulunduğu diğer element’e eklemek zorunda kaldık. Bu tür yapılandırma oluşturmak istediğimiz XML dokümanını göz önünde bulundurursak, biraz tersten bir yaklaşım. XLinq bize, XML dokümanını daha doğrudan yaratmamızı sağlayan fonksiyonaliteyi sağlamaktadır.

XML programlaması yaparken fokunuz genellikle element’ler ve attribute’lardır, XML’in ağaç yapısı ile oynarız, yeni dallar oluştururuz veya element’lerin değerlerini değiştiririz. XML DOM modelinde XML Document içerisindeki tüm element’ler bu dokümanın bağlamında yaşar. Bir element’i XML DOM kullanarak nasıl tanımlayacağımıza bakalım:

        Dim PO As New XmlDocument()

        Dim purchaseOrder = PO.CreateElement("purchaseOrder")

Bu örnekte gördüğümüz gibi puchaseOrder herşeyiyle PO dokümanının bir parçası olarak yaşamaktadır. purchaseOrder’ı başka XmlDocument’larda kullanmamız gerekirse bu element’i diğer dokümanlara taşımamız gerekir. Halbuki aynı şeyi XLinq şu şekilde yapmaktadır:

        XElement name = new XElement("name");

Görülebileceği gibi XLinq, bir element yaratmak için herhangi bir XML Dokümanı yaratmamaktadır.

Aynı dokümanın XLinq versiyonu (API)

        Dim PO = New XElement("purchaseOrder", _

          New XAttribute("orderDate", "1999-10-20"), _

            New XElement("items", _

                New XElement("item", New XAttribute("partNum", "872-AA"), _

                   New XElement("productName", "Lawnmower"), _

                   New XElement("quantity", 1), _

                   New XElement("price", 148.95))))

XML Literal’leri

Yukarıda ilk verdiğimiz XML DOM örneğindeki PO ile ilgili tüm satırları bu örnekle değiştirip çalıştırın. Farkettiğiniz gibi her XElement constructor’ı bir isim, ve sınırsız sayıda XAttribute veya XElement kabul eder. Bu sayede oldukça organize bir şekilde istediğimiz XML ağacını yaratabiliriz. Bu bir XLinq dokümanı yaratmanın API yöntemidir. Malum nedenlerden dolayı C#’da da VB’de de bu yapı aynı şekilde çalışacaktır. VB, XML Literals adını verdiği bir teknoloji ile bu örnekteki XML dokümanını daha da doğrudan oluştumanıza olanak verir:

        Dim VBPO =

                      

                         

                            Lawnmower

                            1

                            148.95

                          

                        

                      

XML Literalları kullanarak Visual Studio’da bu yapıyı kurduğunuz zaman Visual Studio IDE’si size hem XML dokümanını renklendirir, hem de dokümanı tek satıra indirebilmenizi sağlayacak [-] işaretlerini satır kenarında çıkarır. Bu sayede bir VB dokümanında çok büyük bir XML dokümanını görsel olarak çok yer kaplamayacak şekilde saklayabiliriz.

Visual Basic XML Literal konusunda tam destekle gelmektedir. XML Literal motoru oluşturduğunuz XML dokümanında değişiklikler yaptığınızda bu değişiklikleri dokümanın geri kalanına yansıtır. Bir iki örnek verelim. Az önce oluşturduğumuz XML kodunda örneğin ’ı olarak değiştirelim. Bu değişikliği yaptığımız anda, dokümanın devamındaki , olarak değişecektir. Bundan farklı olarak örneğin price’in altına element’i tagi’ni açalım. Bir kaç kelime tanım girelim, sonra da tag’i ile kapatmak yerine ile kapatalım. Bunu yapıp kodda başka bir yere geçtiğimiz anda tag’i ile otomatik olarak değiştirilecektir. (Bu değişiklikleri geri düzeltin).

 Expression Holes

XML Literallere baktığımızda aklımıza şu sorun gelebilir: “Peki, ben element’lerin ve attribute’ların adını ve içeriğini bir veritabanından nasıl alabilirim?” İşte bu noktada Expression Holes olarak adlandırılmı yapısı VB XLinq tarafından sunulmaktadır. XML Literal’lerin içerisinde iken yazdığınız VB kodunda tanımlanmış bir değişkeni kullanmak veya bir VB kodu eklemek istiyorsanız Expression Holes’u kullanabilirsiniz.

        Dim name = "item"

        Dim price = 148.95

        Dim partNum = "872-AA"

        Dim VBP0 =

                      

                           < partNum=>

                               Lawnmower

                               1

                              

                          

                        

                      

Görebileceğiniz gibi burada VBde tanımlanmış olan name, price, partNum gibi değerleri Element’lerin ve Attribute’ların adları ve değerleri yerine kullanabiliyoruz. Dikkatinizi çekecek olursa, items element’inin içindeki ilk element’in adı bir değişken tarafından (name) belirlendiği için, bu element’in bitiş tag’i olarak işaretlenmiş durumda. Program çalışırken bu değere göre elementin yapısı şekillenecek.

Programımızı çalıştırdığımızda aynı sonucu elde ettiğimizi görebiliriz.

XLinq’de Namespaceler

Gelin, XML dokümanlarında son derece sık kullanılan bir yapıyı, namespace’leri XLinq dokümanımıza nasıl ekleyebileceğimize bakalım. Örneğin http://foobar namespace’ini purchaseOrder element’ine eklemek istiyoruz. Bu durumda, XLinq API’ının XNamespace sınıfı yardımcı olacak bize:/p>

        Dim x = XNamespace.Get("http://foobar")

 

        Dim PO = New XElement(x + "purchaseOrder", New XAttribute(XNamespace.Xmlns + "ns", x), _

          New XAttribute("orderDate", "1999-10-20"), _

            New XElement(x + "items", _

                New XElement("item", New XAttribute("partNum", "872-AA"), _

                   New XElement("productName", "Lawnmower"), _

                   New XElement("quantity", 1), _

                   New XElement("price", 148.95))))

Burada x değişkeninin XNamespace sınıfına ait olduğunu ve http://foobar namespace’ini gösterdiğini belirledikten sonra, daha önce oluşturduğumuz purchaseOrder XElement’xmlns:ns attribute’u ekliyoruz (başka bir değişle, purchaseOrder element’i ve altında geçerli olmak üzere ns namespace prefix’ini http://foobar ile ilişkilendiriyoruz, aşağıdaki dokümana bakın). Sonrasında da XElement’in adının başına bu xmlns attribute’unun değeri olan ve namespace’i içeren x’i ilişkilendiriyoruz. items element’ini de aynı namespace’e almak istersek items’ın başına da x’i ekliyoruz.

Sonuç XML dokümanı:

 

   

      Lawnmower

      1

      148.95

   

 

XML Literals’da Expression Holes kullanarak bu yapı uygulanabilir, fakat daha kolay bir yolu daha var. Aşağıdaki örnek de görülebileceği gibi, Module’un başına Imports ile bir prefix’i bir namespace kaynağına ilişkilendirip sonra da bu prefix’i namespace’e dahil olmasını istediğimiz elemanlarda kullanabiliriz. XLinq otomatikman XNamespace objesini oluşturup gerekli xmlns attribute’larını koyacaktır.

Imports ns = "http://foobar"

Module Module1

    Sub Main()

        Dim VBP0 =

                      

                           < partNum=>

                               Lawnmower

                               1

                              

                          

                        

                      

        Console.WriteLine(VBP0)

        Console.ReadLine()

    End Sub

End Module

XML içerisinde XML üretmek

Şu ana kadar bir XML element’inin değerini hep daha önce atanmış bir değerden aldık. Peki bir Expression Hole’un içerisinde XML element’leri oluşturmak isteseydik ne yapmamız gerekiyordu? Aşağıdaki XLinq querysini inceleyelim. arr listesi içerisinde bulunan sayılardan 3den küçük olanını seçiyoruz, ve bu sayıları sayy şeklinde işaretliyoruz. result değişkeni aslında bir IEnumerable (Of XElement) halinde saklanıyor. Bu result değişkenini yukarıdaki örneğimizdeki quantity element’imizin içerisinde kullanmak istersek aslında sayı sayı sayı şeklinde bir yapı oluşturmuş oluruz.

       Dim arr = {1, 2, 3, 4}

       Dim result = From I In arr _

                    Where i < 3 _

                    Select

Aslında bu işin daha da kolayı, result değişkenini hiç tanımlamayıp XLinq sorgusunu doğrudan quantity’nin içinde yapmak:

        Dim VBP0 =

                      

                           < partNum=>

                               Lawnmower

                              

                                          Where i

                                          Select %>

                              

                              

                          

                        

                      

Bu dokümanını bastırırsak şu şekilde bir çıktı alırız::

 

   

      Lawnmower

     

        1

        2

     

      148.95

   

 

XLinq dokümanının değerlerine erişmek

Bir çok farklı yöntemle XML’in hafızada XLinq ile nasıl yaratılacağını gördük, daha fazla bilgiyi XLinq dokümantasyonundan rahatça edinebilirsiniz. Şimdi, gelin, elimizdeli bu XLinq Element’ini nasıl sorgulayacağımıza bakalım.

XLinq bir XPath fonksiyonelitesini sağlayan Element(), Elements(), Descendants(), Attribute() ve Attributes() gibi methodları kullanmanıza olanak vermektedir. Bir element’in veya bir attribute’un değerine erişmek istiyorsak bunun iki yolu vardır: birincisi attribute’u veya element’i bir veri tipine cast etmek, ikincisi ise .Value değişkenini kullanmak. İlk yol bize o değeri istediğimiz data tipinde verir, ikinci yol ise o değerin metin değerini verir, XML metin tabanlı bir dil olduğundan hafızada ne tutuluyorsa o değeri birebir döndürür.

Console.WriteLine(VBPO.Element(x + "items").Element("item").Element("price").Value)

XLinq VB’de XML Axis Properties olarak adlandırılan özel bir yapı sunmuştur: .Element("abc") yerine kullanabiliriz. Yukarıdaki örneğin Axis özellikleriyle yazımı şu şekilde olur:

Console.WriteLine(VBPO....Value)

Dikkat edeceğiniz üzere XNamespace objesini x’e atamıştık bu yazının öncesinde, ve Module’umuzun üzerine de bir namespace tanımı yapmıştık ns prefixine atamıştık bu tanımı da. Namespaceleri belirlenmiş bir XElement’in değerlerine erişmek için bu namespace tanımlamalarını kullanmamız gerekir. Yoksa farklı namespacedeki elemanlara belirli erişemeyiz.

VBPO element’imizde sadece bir tane price element’i olduğunu bildiğimiz için Descendants() fonksiyonunu kullanmamız mümkün:

Console.WriteLine(VBPO.Descendants().ElementAt(0).Value)

Console.WriteLine(VBPO....Value)

Attribute’lara erişimimiz Axis özellikleriyle @ işareti ile sağlanır:

Console.WriteLine(VBPONS.Attribute("orderDate").Value)

Console.WriteLine(VBPONS.@orderDate.Value)

Sonuç

XLinq çok kısa bir sürede yüksek bir ivme ile gelişip yeni bir teknoloji standardı olarak karşımıza çıkıyor. XML DOM’un eksik yönlerini kapatmayı hedefleyen bu dil Visual Basic desteği ile oldukça güçlü ve kolay veriye yönelik bir yazılım ortamı sunuyor. Microsoft’un kendi teknolojisi olan bu yeni dil ve yapı, ileride .NET yazılımcılarının işini çok kolaylaştıracak

Döküman Arama

Başlık :

Kapat