ElementTree ile XML oluşturmaya giriş

Uzun zaman önce söz verdiğim bu yazıyı şimdi yazayım dedim. Neyse, lafı uzatmadan başlayalım. Daha önce ElementTree‘nin ne kadar güzel bir XML kitaplığı olduğundan bahsetmiştim. XML yapıları oluşturma konusunda da, ayrıştırma konusunda olduğu kadar pratik ve başarılı. Giriş düzeyinde bahsedeyim.

Şöyle bir veri yığınını XML formatına dönüştürmek istiyorsunuz diyelim ki:

source = "bash"
pkgname = "bash"
version = "4.2"
summary = "The standard GNU Bourne again shell"
homepage = "http://tiswww.case.edu/php/chet/bash/bashtop.html"
dependency = "ncurses"

Oluşturmak istediğimiz XML formatı da tam olarak şöyle:

<package source="bash">
    <name version="4.1_p7">bash</name>
    <summary>The standard GNU Bourne again shell</summary>
    <homepage>http://tiswww.case.edu/php/chet/bash/bashtop.html</homepage>
    <dependencies>
        <dependency>ncurses</dependency>
    </dependencies>
</package>

Bu işi yapacak Python kodu ise:

import xml.etree.cElementTree as iks

source = "bash"
pkgname = "bash"
version = "4.2"
summary = "The standard GNU Bourne again shell"
homepage = "http://tiswww.case.edu/php/chet/bash/bashtop.html"
dependency = "ncurses"

root = iks.Element("package")
root.set("source", version)

name_tag = iks.SubElement(root, "name")
name_tag.set("version", version)
name_tag.text = pkgname

summary_tag = iks.SubElement(root, "summary")
summary_tag.text = summary

homepage_tag = iks.SubElement(root, "homepage")
homepage_tag.text = homepage

dependencies_tag = iks.SubElement(root, "dependencies")
dependency_tag = iks.SubElement(dependencies_tag, "dependency")
dependency_tag.text = dependency

print(iks.tostring(root))

ElementTree’den bahsederken cElementTree kullanmama dikkat edin. cElementTree, tahmin edebileceğiniz gibi ElementTree’nin C ile gerçeklenmiş hali. Hız açısından her zaman C ile yazılmış modülleri tercih edin. Python 2 serisindeki pickle/cPickle ikilisi de buna bir örnek teşkil ediyor.

Kodu açıklamak istiyorum ama; açıklanacak fazla birşey de göremiyorum. Gayet sade ve anlaşılır. Biraz açıklama yapayım yine de: XML yapısındaki ilk girdiyi(örnekte root yani, “package”) oluşturmak için Element metodunu kullanıyoruz. Daha sonra alt girdiler oluşturmak içinse SubElement metodu devreye giriyor. attribute atamak için set metodu kullanılırken girdilere değer vermek için(doğru bir ifade mi?) text metodunu kullanmak yeterli oluyor. Bu kadar basit bir kodu nasıl açıklayacağımı pek bilemedim gördüğünüz gibi… :)

Aslında önemli bir nokta var. ElementTree, tüm olumlu özelliklerine rağmen XML dosyaları oluşturmak konusunda biraz sıkıntılı. Yukarıdaki kod bloğunun nasıl çıktı verdiğine bakalım:

<package source="4.2"><name version="4.2">bash</name><summary>The standard GNU Bourne again shell</summary><homepage>http://tiswww.case.edu/php/chet/bash/bashtop.html</homepage><dependencies><dependency>ncurses</dependency></dependencies></package>

Oluşturacağınız XML dosyasını insanlar okuyacaksa çok talihsiz bir çıktı bu. İşin kötüsü; kitaplık, girintileme sorununu çözmek için bir fonksiyon da sağlamıyor. Sorunun çözümü ElementTree’nin internet sitesinde bir yerlerde yatıyor. Aşağıdaki fonksiyonu koda eklediğimizde çıktı başta verdiğim XML yapısı gibi düzgün görünecek.

def indent(elem, level = 0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        #if not elem.tail or not elem.tail.strip():
        #    elem.tail = i
        for e in elem:
            indent(e, level+1)
            if not e.tail or not e.tail.strip():
                e.tail = i + "  "
        if not e.tail or not e.tail.strip():
            e.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

Çıktıyı ekrana yazdırmadan önce root değişkeni bu fonksiyondan geçmeli. Yani:

.....
..
indent(root)
print(iks.tostring(root))

Girintilemenin doğru yapıldığını göreceksiniz.

ElementTree’nin benim burada anlattığımdan kat kat fazla yeteneği var. Orjinal dökümantasyonu inceleyerek bolca bilgi edinebilirsiniz. Benimkisi biraz “böyle bir şey de var himm” denilecek türden bir yazı oldu. Ufak bir bilgi notu gibi…

Yorum yapın

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Değiştir )

Twitter picture

You are commenting using your Twitter account. Log Out / Değiştir )

Facebook photo

You are commenting using your Facebook account. Log Out / Değiştir )

Connecting to %s


Takip Et

Get every new post delivered to your Inbox.

Join 57 other followers