Makale Özeti

XML gün geçtikçe daha çok yerde karşımıza çıkan ve günümüz bilişim dünyasında kullanmanın kaçınılmaz olduğu bir yapı halini aldı. Bu dokuman ile Microsoft .NET Platformunda XML kullanımını detaylı olarak ele alarak XML ve kullanımını konusunda akla gelebilecek sorulara yanıt üretmeyi hedefliyoruz.

Makale

XML gün geçtikçe daha çok yerde karşımıza çıkan ve günümüz bilişim dünyasında kullanmanın kaçınılmaz olduğu bir yapı halini aldı. Bu dokuman ile Microsoft .NET Platformunda XML kullanımını detaylı olarak ele alarak XML ve kullanımını konusunda akla gelebilecek sorulara yanıt üretmeyi hedefliyoruz.

Dokumanda ele alacağımız konuları aşağıdaki ana başlıklar altında inceliyor olacağız;

Ø       XML Dokuman Nesne Modeli

Ø       XmlReader ve XmlWriter ile Çalışmak

Ø       XpathNavigator İle Çalışmak

Ø       XML Schema Nesne Modeli

Ø       XML Dosyasının Doğrulanması

Ø       XML ve DataSet’ler İle Çalışmak

XML Dokuman Nesne Modeli
Tamamen farklı sistemlerin birbirleri ile iletişim kurmalarını sağlamak için tüm sistemler tarafından anlaşılabilecek bir standarta ihtiyaç duyarız. Tüm sistemlerin metin tabanlı verileri yorumlayabiliyor olmasından dolayı çözüm olarak metin tabanlı bir standart kullanırız. XML, metin tabanlı yapısı sayesinde tüm sistemler tarafından kullanılabilirken, sağladığı pek çok ek özellikle uygulama geliştiriciler açısından kritik pek çok gereksinimi karşıladığı için günümüzde IT projelerinde ortak standart olarak kullanılmakta ve kullanım oranı gün geçtikçe artmaktadır. Aşağıda well-formed bir xml dokumanı örneği yer almaktadır; 

<?xml version= "1.0"?>

    <personel>

        <calisan>

            <Ad>John</Ad>

            <Soyad>Doe</Soyad>

            <DogumTarihi>08/09/1968</DogumTarihi>

            <DateOfJoining>04/01/1992</DateOfJoining>

            <Adres>2010 Stanley Dr., Charlotte, NC 28273</Adres>

            <Unvan>Associate Consultant</Unvan>

            <Derece>12</Derece>

        </calisan>

        <calisan>

            <Ad>Luis</Ad>

            <Soyad>Bonifaz</Soyad>

            <DogumTarihi>01/12/1972</DogumTarihi>

            <DateOfJoining>06/01/2000</DateOfJoining>

            <Adres>7862 Freepoint Pkwy, Tampa, FL 33624</Adres>

            <Unvan>Developer</Unvan>

            <Derece>4</Derece>

        </calisan>

    </personel>

Yukarıdaki well-formed XML kodu iki çalışana dair personel bilgilerini içermektedir. Well-formed terimini her açılış etiketi için bir kapanış etiketi barındıran, kurallara uygun bir XML dokumanını tanımlamak için kullanıyoruz. Örneğin her <calisan> etiketi için bir </calisan> kapanış etiketi yer almalıdır. Well-formed bir XML dokumanını veriyi ve XML dokumanının içinde yer alan veriler arasındaki ilişkileri tanımlayan bir document type definition (DTD) veya XML Schema ile ilişkilendirebilirsiniz. DTD’ler, XML dokumanlarına göre daha farklı bir söz dizimine sahiptir. XML Schema ise XML dokumanındaki element ve attribute’leri tanımlayan ve gerektiğinde tür bilgilerini içerebilen dokumanlardır. DTD ve XML Schema dosyalarını XML dokumanlarını tanımlamak ve doğrulamak için kullanırız. XML dokumanlarının doğrulanması konusunu ilerleyen bölümlerde ele alıyor olacağız.

XML Dokuman nesne modeli, XML dokumanlarını programatik olarak okumamızı ve XML dokumanları üzerinde değişiklikler yapabilmemizi sağlar.

XML Dokuman Nesne Modeli
XML Document Object Model (XML DOM) sınıfı bellekteki XML dokumanının bir temsilidir. DOM sınıfı XML dokumanlarını okumamızı, yazmamızı ve dokumanlar üzerinde değişiklikler yapmamızı sağlar. .NET Framework XML dokumanı içinde hareket etmemizi ve ihtiyaç duyduğumuz verilere erişmemizi sağlayan sınıfları sunar. Her XML dokumanı parent ve child node (düğüm)lardan oluşur. Yukarıda yer alan XML dokumanında <personel> parent node dur. <personel> parent node unun child node u ise <calisan> node udur. <calisan> node u pek çok child node içerebilir. <Ad> ve <Soyad> gibi aynı seviyede yer alan nodelar sibling olarak adlandırılır.

XML DOM farklı node türleri içerir. Aşağıdaki liste sıklıkla kullanacağımız nodeları ve açıklamalarını içermektedir.

DOM Node Türü

Açıklama

Document

Bu node türü tüm diğer nodelar için container görevi görür ve document root olarak nitelendirilir.

DocumentType

Bu node türü <!DOCTYPE> nodeunu temsil eder.

Element

Bu node türü element nodelarını temsil eder.

Attribute

Bu node türü element nodelarına ait attribute’leri temsil eder.

Comment

Bu node türü yorum nodelarını temsil eder.

Text

Bu node türü bir node’a veya attribute’a ait metni temsil eder.

XML dokumanlarından veri okumak için aynı zamanda Simple API for XML (SAX) kullanabilirsiniz. DOM’dan farklı olarak SAX tüm XML dokumanını belleğe yüklemez, bunun yerine içeriği sıralı olarak okur ve XML dokumanını okudukç olaylar oluşturur. SAX, XML dokumanını belleğe yüklemediği için büyük XML dosyalarını okumak için iyi bir alternatif olarak görebiliriz ancak gelişmiş aramaları gerçekleştirmek için ihtiyaç duyulan veri yapılarını sağlamıyor olması bizim için bir dezavantajdır. Ek olarak XML dokumanı üzerinde değişiklik yapmak istediğiniz durumlarda SAX kullanamayız.

XML dokumanları ile çalışmanın bir diğer yolu ise .NET Framework tarafından sunulan XMLReader sınıfını kullanmaktır. XMLReader sınıfı read-only ve forward-only bir yapı ile XML dokumanlarını okuma imkanı verir. XML DOM’un aksine XMLReader sınıfı da XML dokumanının tamamını belleğe yüklemez.

XML DOM kullanarak XML dosyaların okumak ve güncellemek için çeşitli nesneleri ele almadan önce XML dokumanlarının bellekte nasıl yapılandığını bilmemiz gerekmektedir. Root node document node’udur ve XmlDocument nesnesi ile temsil edilir. XmlDocument nesnesi XmlNode sınıfından türetilmiştir. XmlDocument nesnesi XML dokumanlarının açılması ve kaydedilmesi gibi işlemleri gerçekleştirmek için kullanılır. Ek olarak XmlDocument nesnesini, dokuman içinde yer alan tüm node’lara erişmek için kullanabiliriz.

Aşağıdaki kod örneği bir XML dokumanının XML DOM kullanarak yüklenmesini örneklemektedir;

Imports System

Imports System.IO

Imports System.Xml

 

Module Module1

    Sub Main()

        Dim myDocument As New XmlDocument

        myDocument.Load("emp.xml")

        Console.WriteLine(myDocument.InnerXml.ToString)

        Console.ReadLine()

    End Sub

End Module

Bu kod XmlDocument nesnesini kullanarak XML dokumanını myVariable adlı değişkene yüklemektedir. XML dokumanını bir değişkene yüklemenin iki yolu vardır. Load metodunu kullanabilir ve yüklenecek dosya adını arguman olarak belirtebilir veya alternatif olarak LoadXml metodunu kullanabilir ve arguman olarak XML verisini belirtebilirsiniz. Aşağdaki kod örneği LoadXML metodunun kullanımını örneklemektedir;

Imports System

Imports System.IO

Imports System.Xml

 

Module Module1

    Sub Main()

        Dim myDocument As New XmlDocument

 

        myDocument.LoadXml("<personel>" & _

            "<calisan>" & _

            "<Ad>John</Ad>" & _

            "<Soyad>Doe</Soyad>" & _

            "<DogumTarihi>08/09/1968</DogumTarihi>" & _

            "<DateOfJoining>04/01/1992</DateOfJoining>" & _

            "<Adres>2010 Stanley Dr., Charlotte, NC 28273</Adres>" & _

            "<Unvan>Associate Consultant</Unvan>" & _

            "<Derece>12</Derece>" & _

            "</calisan>" & _

            "<calisan>" & _

            "<Ad>Luis</Ad>" & _

            "<Soyad>Bonifaz</Soyad>" & _

            "<DogumTarihi>01/12/1972</DogumTarihi>" & _

            "<DateOfJoining>06/01/2000</DateOfJoining>" & _

            "<Adres>7862 Freepoint Pkwy, Tampa, FL 33624</Adres>" & _

            "<Unvan>Developer</Unvan>" & _

            "<Derece>4</Derece>" & _

            "</calisan>" & _

            "</personel>")

        Console.WriteLine(myDocument.InnerXml.ToString)

        Console.ReadLine()

    End Sub

End Module

XML verisini yazmak için de XmlDocument nesnesini kullanabiliriz. XML verisi yazmak için Save metodunu kullanmamız gerekir. Aşağıdaki kod örneği Save metodunun kullanımını örneklemektedir.

 

Imports System

Imports System.IO

Imports System.Xml

 

Module Module1

    Sub Main()

        Dim myDocument As New XmlDocument

        Dim XmlData As String

        XmlData = "<personel>" & _

            "<calisan>" & _

            "<Ad>John</Ad>" & _

            "<Soyad>Doe</Soyad>" & _

            "<DogumTarihi>08/09/1968</DogumTarihi>" & _

            "<DateOfJoining>04/01/1992</DateOfJoining>" & _

            "<Adres>2010 Stanley Dr., Charlotte, NC 28273</Adres>" & _

            "<Unvan>Associate Consultant</Unvan>" & _

            "<Derece>12</Derece>" & _

            "</calisan>" & _

            "<calisan>" & _

            "<Ad>Luis</Ad>" & _

            "<Soyad>Bonifaz</Soyad>" & _

            "<DogumTarihi>01/12/1972</DogumTarihi>" & _

            "<DateOfJoining>06/01/2000</DateOfJoining>" & _

            "<Adres>7862 Freepoint Pkwy, Tampa, FL 33624</Adres>" & _

            "<Unvan>Developer</Unvan>" & _

            "<Derece>4</Derece>" & _

            "</calisan>" & _

            "</personel>"

        myDocument.LoadXml(XmlData)

        myDocument.Save("newemp.xml")

        Console.WriteLine(myDocument.InnerXml.ToString)

        Console.ReadLine()

    End Sub

End Module

Bir XML Parser Oluşturalım

XML dokumanlarının nasıl yükleneceğini ve kaydedileceğini öğrendiğimize göre sıra bir XML dosyasını okuyarak içeriğini konsol ekranında görüntüleyecek bir örnek geliştirebiliriz. Aşağıdaki kod örneği bu işlemi gerçekleştirmektedir;

Imports System

Imports System.IO

Imports System.Xml

 

Module Module1

    Sub Main()

        Dim myDocument As New XmlDocument

        Dim xmlData As String

        myDocument.Load("personel.xml")

        Dim node1 As XmlNode

        Dim i As Integer

        Dim count As Integer

        count = 0

        i = 1

        node1 = myDocument.ChildNodes(1)

        For Each node1 In node1.ChildNodes

            Console.WriteLine(vbCrLf)

            Console.WriteLine("{0} numaralı node un altında bulunan elemanlar:", i)

            Console.WriteLine("---------------------------------------")

            Dim node2 As XmlNode

            For Each node2 In node1.ChildNodes

                Console.WriteLine( _

                myDocument.DocumentElement.FirstChild.ChildNodes _

                (count).Name + ": " + node2.FirstChild.Value)

                count = count + 1

            Next

            i = i + 1

            count = 0

        Next

        Console.WriteLine(vbCrLf)

        Console.WriteLine("Çıkmak için <Enter> tuşuna basınız")

        Console.ReadLine()

    End Sub

End Module

XmlReader ve XmlWriter İle Çalışmak

System.Xml namespace’i XML verilerini stream’lerden veya XML dokumanlarından okumamızı ve yazmamızı sağlayan XmlReader ve XmlWriter sınıflarını sunar. Bu base class’ları kullanarak kendi ihtiyaçlarımız doğrultusunda özelleştirdiğimiz sınıflarımızı oluşturabiliriz. Bu bölümde XmReader ve XmlWriter sınıfları tarafından sunulan özellikleri ele alıyor olacağız.

XmlReader
XmlReader sınıfı bir stream veya XML dokumanı ile XML verisine erişmenize olanak tanır. Bu sınıf bize XML verilerine hızlı, önbelleklenemeyen, read-only, forward-only erişim imkanı verir. XmlReader soyut bir sınıftr ve kendisinden türetilen sınıfların XML verilerinin element ve attribute'lerine erişmesine olanak tanıyan metodları içermektedir. XmlReader sınıflarını XML dokumanındaki bir node'un derinliğini belirlemek, node'un attribute'leri olup olmadığını denetlemek ve varsa attribute sayısını ve bir attributre'ın değerini öğrenmek için kullanırız. XmlTextReader sınıfı XmlReader sınıfından türetilmiş bir sınıftır. XmltextReader sınıfını XML verisini okumak için kullanırız ancak XmltextReader sınıfı DTD veya Schema bilgilerine erişme ve doğrulama imkanı vermez. Yine XmlReader sınıfından türetilmiş bir sınıf olan XmlValidatingReader sınıfı ise XML verisini okuma imkanının yanı sıra DTD ve Schema doğrulama işlemlerini de destekler. XmlValidatingReader sınıfını ilerleyen bölümlerde ele alıyor olacağız.

XmlTextReader ile XML Verisini Okumak

XmlTextReader sınıfı XML verisine hızlı bir şekilde erişme ihtiyacı olduğunda kullanabileceğimiz bir sınıftır ancak yukarıda da belirttiğimiz gibi bu sınıf DTD veya Schema doğrulama özellikleri sunmamaktadır. XmlTextReader sınıfını tüm XML verisini DOM ile belleğe yükleme ihtiyacı duymadığımız durumlarda kullanırız. XmlTextReader sınıfının en sık kullanacağımız metod ve özellikleri aşağıdaki tabloda listelenmiştir;

Üye

Açıklama

Özellikler

 

AttributeCount

Bulunulan node’da yer alan attribute sayısını döner.

Depth

Bulunulan node’un XML dokumanındaki derinliğini döner.

HasAttributes

Bulunulan node’un attribute’ları olup olmadığını Boolean türünden döner.

HasValue

Bulunulan node’un bir değer içerip içermediğini Boolean türünden döner.

IsEmptyElement

Bulunulan node’un boş olup olmadığını döner.

Item

Attribute’ın değerini String türünden döner.

Value

Bulunulan node’un metin değerini döner.

Metodlar

 

IsStartElement

Bulunulan element’in başlangıç element’i olup olmadığını denetler.

MoveToElement

Bulunulan attribute node’undan farklı bir element’e geçiş yapar.

MoveToFirstAttribute

İlk attribute’a geçiş yapar.

MoveToNextAttribute

Bir sonraki attribute’a geçiş yapar.

Read

Stream’deki bir sonraki node’u okur.

ReadAttributeValue

Attribute değerini okur ve değeri bir veya daha fazla node’a parse eder.

ReadString

Bir element veya node’daki değeri okur.

ReadStartElement

Bulunulan node’un bir element olup olmadığını denetler ve okuyucuyu bir sonraki node’a taşır.

ReadEndElement

Bulunulan node’un bir kapanış etiketi olup olmadığını denetler ve okuyucuyu bir sonraki node’a taşır.

Skip

Bulunulan node’un child node’unu geçer.

Aşağıdaki kod örneği XmlTextReader nesnesi ile XML dokumanının okunmasını örneklmektedir;

Dim textReader As New XmlTextReader("personel.xml")

XmlTextReader nesnesini şu şekilde de kullanabiliriz;

Dim stream As New System.IO.StringReader("<personel>" & _

"<calisan>" & _

"<Ad>John</Ad>" & _

"<Soyad>Doe</Soyad>" & _

"<DogumTarihi>08/09/1968</DogumTarihi>" & _

"<DateOfJoining>04/01/1992</DateOfJoining>" & _

"<Adres>2010 Stanley Dr., Charlotte, NC 28273</Adres>" & _

"<Unvan>Associate Consultant</Unvan>" & _

"<Derece>12</Derece>" & _

"</calisan>" & _

"<calisan>" & _

"<Ad>Luis</Ad>" & _

"<Soyad>Bonifaz</Soyad>" & _

"<DogumTarihi>01/12/1972</DogumTarihi>" & _

"<DateOfJoining>06/01/2000</DateOfJoining>" & _

"<Adres>7862 Freepoint Pkwy, Tampa, FL 33624</Adres>" & _

"<Unvan>Developer</Unvan>" & _

"<Derece>4</Derece>" & _

"</calisan>" & _

"</personel>")


Dim textReader As New XmlTextReader(Stream)

Aşağıdaki kod örneği ise XmlTextReader sınıfı aracılığıyla XML verisinin okunması ve görüntülenmesini örneklemektedir;

   Dim reader As New XmlTextReader("personel.xml")

   While reader.Read()

       Select Case reader.NodeType

           Case XmlNodeType.Element

               Console.Write("<" + reader.Name)

               While (reader.MoveToNextAttribute())

                   Console.Write(" " & reader.Name & "='" & _

                       reader.Value & "'")

               End While

               Console.Write(">")

               If reader.HasAttributes Then

                   While reader.MoveToNextAttribute

                       Console.Write(" " & reader.Value & " ")

                   End While

               End If

           Case XmlNodeType.Text

               Console.Write(reader.Value)

           Case XmlNodeType.EndElement

               Console.WriteLine(("</" & reader.Name & ">"))

       End Select

   End While

Sanırım XML verisinin okunması ile ilgili yeterince örnek verdik, sırada XmlWriter sınıfını kullanarak XML dosyaları oluşturmak var..

XmlWriter
XmlWriter sınıfı XML Stream’leri oluşturma ve well-formed XML dokumanları oluşturmamızı sağlayan bir abstract sınıftır. Bir output stream kullanarak birden çok dokuman yazmak, stream içine geçerli isim ve token’lar yazmak, binary veriyi encode ederek metinsel çıktı oluşturmak (yazmak), çıktıyı yönetmek istediğimiz durumlarda XmlWriter sınıfını kullanırız. XmlWriter sınıfından türetilmiş olan XmlTextWriter sınıfı ise XML verilerini bir dosyaya, stream’e, konsole v.b. alanlara yazmak için ihtiyaç duyduğumuz metod ve özellikleri sunar. XmlTextWriter sınıfının en sık kullanılan özellik ve metodları aşağıdaki gibidir;

Üye

Açıklama

Özellikler

 

BaseStream

XmlTextWriter’ın çıktıyı yazarken kullanacağı stream’i alır.

Formatting

Çıktının nasıl biçimlendirileceğini belirler. Indented veya None değerlerinden birini alır. Indented değeri seçildiğinde child elementler Indentation ve IndentChar kullanılarak girintili yazılır.

Indentation

Child elementler yazılırken kaç adet IndentChar kullanılacağını belirtir.

IndentChar

Girinti oluşturmak için kullanılacak karakteri belirtmek veya belirlenmiş karakteri almak için kullanılır. Formatting.Indented seçiliyken aktif hale gelir.

WriteState

Yazıcının (writer) durumunu öğrenmek için kullanılır. Geçerli değerler; Start, Element, Attribute, Contect, Prolog ve Closed değerleridir.

Metodlar

 

WriteStartDocument

XML dokumanının başlangıcı olarak aşağıdaki ifadeyi yazar;
<?xml version="1.0" ?>

WriteStartElement

Belirtilen element için başlangıç etiketini yazar.

WriteElementString

Belirtilen element için metinsel değeri yazar.

WriteStartAttribute

Bir attribute’ın başlangıcını yazar.

WriteAttributeString

Attribute için belirtilen değeri yazar.

WriteEndAttribute

Attribute için kapanışı yazar.

WriteEndElement

Belirtilen element için kapanış etiketini yazar.

XmlTextWriter ile XML Verisini Yazmak
Aşağıdaki kod örneği XmlTextWriter nesnesi ile XML verisini bir dosyaya yazmayı örneklemektedir;

Dim textWriter As New XmlTextWriter("personel.xml", _

     System.Text.Encoding.UTF8)

textWriter.Formatting = Formatting.Indented

textWriter.WriteStartDocument(False)

textWriter.WriteDocType("Personel", Nothing, Nothing, Nothing)

textWriter.WriteComment("Bu dosya personel bilgilerini içerir." & _

    "database")

textWriter.WriteStartElement("Personel")

textWriter.WriteStartElement("Calisan", Nothing)

textWriter.WriteElementString("Ad", "John")

textWriter.WriteElementString("Soyad", "Doe")

textWriter.WriteElementString("DogumTarihi", "08/09/1968")

textWriter.WriteElementString("IseGirisTarihi", "04/01/1992")

textWriter.WriteEndElement()

textWriter.WriteEndElement()

 

'XML verisini dosyaya yaz ve textWriter'ı kapat

textWriter.Flush()

textWriter.Close()

Console.WriteLine("Çıkmak için <Enter> tuşuna basın.")

Console.Read()

Makalenin ikinci bölümünde kaldığımız yerden devam ediyor olacağız..

Kaynak: Bu dokuman MCSD Self Paced Training Kit’in “Accessing and Manipulating XML Data” bölümü kaynak alınarak hazırlanmıştır.

Kadir Sümerkent
kadir@sumerkent.com