Öncelikle Yüksek Lisans öğrencim “Svetoslav Martinov Iliyanov“a teşekkürler. Bu bölümde Python ortamında XML Processing – JSON Serialization konularını göreceğiz.
XML diğer adıyla The Extensible Markup Language HTML ve SGML gibi bir işaretleme dilidir. Taşınabilir, Açık kaynak kodlu olması ve diğer uygulamalar tarafından okunabilir olması XML dilinin kullanım alanlarını genişletir. Veri taşımak için tasarlanmış olan bir dildir. Örnek verecek olursak bir XML dosyasını notepad’te çalıştırdığımızda aşağıdaki gibi bir formatta kod ile karşılaşırız.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<collection shelf="Yeni Gelenler"> <movie title="Enemy Behind"> <type>Savaş</type> <format>DVD</format> <year>2003</year> <rating>PG</rating> <stars>10</stars> <description>US ve Japonya Savaşı</description> </movie> <movie title="Transformers"> <type>Bilim Kurgu</type> <format>DVD</format> <year>1989</year> <rating>R</rating> <stars>8</stars> <description>Bilimsel Bir Kurgu</description> </movie> <movie title="Trigun"> <type>Animasyon, Macera</type> <format>DVD</format> <episodes>4</episodes> <rating>PG</rating> <stars>10</stars> <description>Muhteşem</description> </movie> <movie title="Ishtar"> <type>Comedy</type> <format>VHS</format> <rating>PG</rating> <stars>2</stars> <description>Sıkıcı bir komedi</description> </movie> </collection> |
XML dosyasındaki veri etiketlerini kendimiz belirleriz. HTML Taglarında olduğu gibi girilen veri <Data TAG>Data</Data TAG> şeklinde yazılır. Kullanımı kolay bir veri depolama yöntemidir. XML dosyasında depolanan veriyi API ler yardımı ile okuyabiliriz. Python da XML işlemleri yapmak için SAX ve DOM, Standart Python Kütüphanesinde bulunan ve XML dosyasından veriyi okumak için en sık kullanılan API’lerden iki tanesidir.
1. SAX ve DOM
1.1. SAX ( Simple API for XML )
SAX , XML ayrıştırma için Java Tabanlı standart bir arayüzdür. XML ayrıştırmak için kendi içerik işleyicinizi oluşturmanız gerekir. Oluşturduğunuz içerik işleyici sizin verdiğiniz belirli olan etiketleri ve belirli olan özellikleri işler. Oluşturulan içerik işleyicisinin ayrıştırma işlemini yapabilmesi için methodları bulunur. Ayrıştırıcı XML dosyasını ayrıştırma esnasında içerik işleyicisinin methodlarını çağırır. startDocument ve endDocument methodu XML dosyasının başında ve sonunda çağırılır. character(text) methodu XML dosyasının karakter verilerini geçirir.
1.1.1. SAX Parser ile ayrıştırma kod Örneği
İçerik işleyici olarak MovieHandler adında bir sınıf oluşturulur. MovieHandler sınıfı XML dosyası içinden kullanmak istediğimiz bilginin bir anlamda iskeletini oluşturmak için kullanılacak sınıftır.def __init__(self) metodu ile XML dosyasında ki sabit etiketler için alan oluşturulur.
1 2 3 4 5 6 7 8 9 10 11 12 |
import xml.sax class MovieHandler( xml.sax.ContentHandler ): def __init__(self): self.CurrentData = "" self.type = "" self.format = "" self.year = "" self.rating = "" self.stars = "" self.description = "" |
MovieHandler sınıfının içinde element başlangıcında çağırılan startElement methodu XML dosyası içerisindeki etiketin “movie” kelimesine eşitliğini kontrol ederek çıktı almamızı sağlar.
1 2 3 4 5 6 7 |
# Eleman Başlangıcında çağırılan Method, yukarıdaki kodun devamı def startElement(self, movie, attributes): self.CurrentData = movie if movie == "movie": print ("\n*****Movie*****" ) title = attributes["title"] print ("Title:", title) |
endElement methodu XML içindeki film bilgisinin etiketlerinin eşitliğini kontrol ederek program çıktımıza yerleştirmemizi sağlar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# Eleman Bitiminde çağırılan Method def endElement(self, tag): if self.CurrentData == "type": print ("Type:", self.type) elif self.CurrentData == "format": print ("Format:", self.format) elif self.CurrentData == "year": print ("Year:", self.year) elif self.CurrentData == "rating": print ("Rating:", self.rating) elif self.CurrentData == "stars": print ("Stars:", self.stars) elif self.CurrentData == "description": print ("Description:", self.description) self.CurrentData = "" |
characters methodu ise etiketlerimizi içindeki içeriği yazdırmamızı sağlar. Ayrıştırıcı her koşulun üzerinden geçerek tüm etiketlerin içeriklerini teker teker okur ve içerikleri icerik değişkenine atar.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Karakter okunurken çağırılan Method. def characters(self, icerik): if self.CurrentData == "type": self.type = icerik elif self.CurrentData == "format": self.format = icerik elif self.CurrentData == "year": self.year = icerik elif self.CurrentData == "rating": self.rating = icerik elif self.CurrentData == "stars": self.stars = icerik elif self.CurrentData == "description": self.description = icerik |
Son adımda parser isimli ayrıştırıcı xml kütüphane sınıfı kullanılarak yaratılır. Ayrıştırıcı 0’ a eşitlenir.Sonraki adımda MovieHandler sınıfından Handler adında nesne oluşturulur. Ayrıştırma işlemini yapabilmek için ayrıştırma metoduna xml dosyasının ismi yazılır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
if ( __name__ == "__main__"): # XML ayrıştırıcı yaratma. parser = xml.sax.make_parser() # Ayrıştırıcı içeriğini 0'a eşitleme. parser.setFeature(xml.sax.handler.feature_namespaces, 0) # MovieHandler sınıfından Handler elemanını yaratma. Handler = MovieHandler() #içerik işleyicisini sınıf elemanı ile kullanılacak. parser.setContentHandler( Handler ) # XML dosyasını ayrıştırma. parser.parse("movies.xml") print(__name__) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
*****Movie***** Title: Enemy Behind Type: Savaş Format: DVD Year: 2003 Rating: PG Stars: 10 Description: US ve Japonya Savaşı *****Movie***** Title: Transformers Type: Bilim Kurgu Format: DVD Year: 1989 Rating: R Stars: 8 Description: Bilimsel Bir Kurgu *****Movie***** Title: Trigun Type: Animasyon, Macera Format: DVD Rating: PG Stars: 10 Description: Muhteşem *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Stars: 2 Description: Sıkıcı bir komedi __main__ |
1.2. Document Object Model (DOM API)
DOM API World Wide Web Consortium (W3C) tarafından tavsiye edilen XML belgelerine erişmek ve düzenlemek için kullanılan API dir. Tüm XML dosyası okunduktan sonra bellekte ağaç biçimde saklanır.
Python Standart kütüphanesinde bulunan XML ayrıştırmak için kullanılan xml.dom kütüphanesi çağırılır. Minidom ayrıştırıcısı ile XML dökümanının tümü DomTree olarak ayrıştırılır. Bütün dökümanın elementleri collection olarak toplanır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from xml.dom.minidom import parse import xml.dom.minidom #minidom ayrıştırıcısı ile XML dökümanının açılması. DomTree = xml.dom.minidom.parse("movies.xml") collection = DomTree.documentElement #if collection.hasAttribute("shelf"): # print ("Root Element : %s" % collection.getAttribute("shelf")) # koleksiyondaki bütün filmleri al. movies = collection.getElementsByTagName ("movie") # her filmin detayını yaz. for movie in movies: if movie.hasAttribute("title"): print ("Title : " + movie.getAttribute("title")) type = movie.getElementsByTagName('type')[0] print ("Type :" + type.childNodes[0].data) format = movie.getElementsByTagName('format')[0] print ("Format :" + format.childNodes[0].data) rating = movie.getElementsByTagName('rating')[0] print ("Rating :" + rating.childNodes[0].data) description = movie.getElementsByTagName('description')[0] print ("Description :" + description.childNodes[0].data) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
Title : Enemy Behind Type :Savaş Format :DVD Rating :PG Description :US ve Japonya Savaşı Title : Transformers Type :Bilim Kurgu Format :DVD Rating :R Description :Bilimsel Bir Kurgu Title : Trigun Type :Animasyon, Macera Format :DVD Rating :PG Description :Muhteşem Title : Ishtar Type :Comedy Format :VHS Rating :PG Description :Sıkıcı bir komedi |
Collection içindeki “movie” etiketine göre movies değişkenine atılır. Movies içinde for döngüsü oluşturularak movies içinde bulunan her filmin detayı yazdırılır. getElementByTagName ile elemanı seçip childNodes[0].data ile elementin içinde bulunan bilgi okunur.
1.3. SAX ve DOM API avantajlar ve dezavantajlar
SAX API ve DOM API temel anlamda bir XML dosyasını okumak için kullanılır. Fakat çalışma yapıları ve özellikleri dolayısıyla aralarından kullanım farkları oluşur. Bu farklılıklardan dolayı ikisininde avantajları ve dezavantajları ortaya çıkar.
SAX | DOM |
XML dökümanına rastgele ulaşımı yoktur. Anlık ve belli bir parçaya işlem yapar. | XML dökümanını hafızada tuttuğu için dökümana rasgele erişimi vardır. |
Karışık aramalar yapmak kolay değildir. | Karışık aramalar yapmak kolaydır. |
Sadece belgeyi okur. | Belgeyi okuma yazma değiştirme ekleme ve silme olanağı verir. |
Tarayıcı tarafından desteklenmez. | Tarayıcı tarafından desteklenir. |
Büyük dosyaları ayrıştırabilir. | Büyük dosya ayrıştırmak için yeterli belleğe ihtiyaç vardır. |
Küçük küme bir bilgiyi getirmek için kullanışlıdır. | Bir veri kümesini getirmek için kullanışlıdır. |
DOM a göre daha hızlı çalışır. | SAX’tan daha yavaştır. |
2. JSON Serialization
Json Javascipt için oluşturulmuş bir veri değişim formatıdır. Veri transferlerinde XML’den daha az yer kaplar. şu anda yazılım geliştirme olarak çok geniş kullanım alanı bulunur. Yazım ve anlam olarak anlaşılabilir bir görünümü vardır.
1 |
{ "isim":"Mehmet", "Yas":30, "Okul":"NKU"} |
Serialization işlemi bir anlamda dönüştürme işlemi olarak da bilinir. Bir json bilgisini Python’un standart kütüphanesinde bulunan json modülü ile işleyebiliriz. Bilgiyi ayrıştırmak için json.loads() methodu kullanılır.
1 2 3 4 5 6 7 8 9 10 |
import json # Json verisi: x = '{ "isim":"Mehmet", "Yas":30, "Okul":"NKU"}' # Veriyi ayrıştır: y = json.loads(x) # Çıktı print(y["Yas"]) |
1 |
30 |
Aynı şekilde bir Python nesnesinide Jsona dönüştürmek için json.dumps() metodu kullanılır.
1 2 3 4 5 6 7 8 9 10 11 |
import json print(json.dumps({"isim": "Mehmet", "Yas": 30})) print(json.dumps(["NKU", "Bilgisayar"])) print(json.dumps(("NKU", "Bilgisayar"))) print(json.dumps("Python")) print(json.dumps(42)) print(json.dumps(31.76)) print(json.dumps(True)) print(json.dumps(False)) print(json.dumps(None)) |
1 2 3 4 5 6 7 8 9 |
{"isim": "Mehmet", "Yas": 30} ["NKU", "Bilgisayar"] ["NKU", "Bilgisayar"] "Python" 42 31.76 true false null |
Python nesne tiplerinden dict, list, tuple, string, int, float, True, False ve None Json veri tipie dönüştürülebilir. Daha fazla bilgi için tıklayın.
Referanslar
- https://www.youtube.com/watch?v=N7GbqTvrWO8&t=60s – Pyhton – Parsing XML with SAX API
- www.slideshare.net
- https://www.tutorialspoint.com/python/python_xml_processing.htm
- https://www.w3schools.com/python/python_json.asp
- https://www.youtube.com/watch?v=4iH-DRVfOD0 – Pyhton Serializing Objects