Converting XML Schema to OWL in Python

Beberapa minggu terakhir saya dapat mainan baru setelah bermain-main dengan scraping (ini bukannya serius belajar malah main-main terus). Persoalannya adalah mengonversi skema data dari bentuk XML Schema ke Ontologi (dalam OWL). XML Schema adalah dokumen XML yang berisi spesifikasi komposisi sebuah dokumen XML.

XML Schema
Pada dasarnya dokumen XML Schema berisi tag-tag “element” yang mengacu pada tag di dokumen yang dispesifikasikan. Untuk mempermudah spesifikasi, jenis dari element ini dibagi menjadi dua tipe yaitu simpleType dan complexType. simpleType adalah tag yang hanya berisi data (numerik/string) sedangkan complexType adalah tipe tag yang memiliki paling tidak atribut tag atau child tag (tag di dalam tag). Komposisi tag di dalam tag dapat berupa komposisi sederhana seperti simpleType tapi memiliki atribut, hanya berisi tag, atau berisi campuran antara teks dengan tag (seperti pada tag body dalam HTML). simpleType dan complexType dapat dideklarasikan tersendiri dan diberi nama. Untuk alasan reusability, maka type dibuat memiliki sifat inheritance dan polymorphism. yaitu suatu tipe dapat dideklarasikan sebagai turunan dari tipe lain yang lalu dispesialisasi/dibatasi atau diperluas.

Web Ontology Language (OWL)
Ontologi merupakan deskripsi formal pengetahuan tentang konsep2 dan hubungan antar konsep. Pada kasus pendefinisian skema basis data, hal yang biasanya dilakukan adalah membuat representasi konseptual (conceptual data model) dari pengetahuan yang dimiliki oleh pengembang sistem. Adanya formalisasi pengetahuan dalam bentuk ontologi bertujuan agar mesin juga dapat ‘mengerti’ sehingga proses integrasi data dapat berlangsung secara otomatis.

Sekian dulu bahasan abstraknya, selanjutnya adalah bagaimana menyelesaikan persoaln konversi XML Schema ke OWL. Sayangnya saya tidak menemukan ada tool konversi yang ditulis dalam python sehingga saya membuat dari awal. Saya menggunakan dua pustaka pembantu yaitu lxml untuk mengurai data dari dokumen XML dan RDFLib untuk membangkitkan ontologi. Sayangnya RDFLib belum memiliki serializer untuk OWL sehingga saya tidak bisa menggunakan format OWL (XML) sebagai keluaran dan sebagai gantinya saya menggunakan format Turtle yang sepertinya juga lebih mudah dibaca oleh manusia.

Sebetulnya makalah yang berisi cara melakukan konversi ini lumayan banyak jadi saya pakai yang paling banyak dikutip dan posisi teratas dari pencarian di google scholar saja:

Bohring, Hannes, and Sören Auer. “Mapping xml to owl ontologies.” Leipziger Informatik-Tage 72 (2005): 147-156.


berdasarkan makalah itu ada 7 aturan konversi dari skema XML ke OWL yaitu:

  1. xsd:element, yang mengandung elemen lain atau memiliki atribut dikonversi menjadi owl:Class atau owl:ObjectProperty
  2. xsd:element, yang tidak mengandung elemen lain atau memiliki atribut (simpleType), dikonversi menjadi owl:DatatypeProperty
  3. xsd:complexType, yang diberi nama (dideklarasikan di luar) dikonversi menjadi owl:Class
  4. xsd:simpleType, yang diberi nama dikonversi jadi owl:DatatypeProperty
  5. xsd:minOccurs dan xsd:maxOccurs, dikonversi menjadi owl:minCardinality dan owl:maxCardinality sebagai property restriction
  6. xsd:sequence dan xsd:all, dikonversi menjadi anonymous class dengan property restriction dengan operator owl:intersectionOf
  7. xsd:choice, dikonversi menjadi anonymous class dengan property restriction dengan kombinasi operator owl:intersectionOf, owl:unionOf, dan owl:complementOf

membaca dokumen XML dengan lxml
Ada 2 cara mengolah dokumen XML yaitu tunggu sampai parsing selesai menjadi representasi di memori atau ikuti proses parsing (berbasis event). Cara pertama dikenal dengan membuat DOM (Document Object Model) sedangkan cara kedua terkenal dengan sebutan SAX.

#cara pertama
from lxml import etree

with open(filename, "r") as f: root = etree.parse(f).getroot()

variabel root merupakan tag paling luar dari dokumen xml dan memiliki pointer ke tag-tag di dalam node tersebut. Salah satu penggunaan ini misalnya jika saya ingin mendapatkan semua node yang memiliki atribut name (untuk resolusi nama) secara rekursif.

def reg_name(tagmap, node):
    if "name" in node.attrib:
        tagmap[node.attrib["name"]] = node
    for child in node:
        reg_name(tagmap, child)

tagmap = {}
#cara kedua
from lxml import etree

ctx = etree.iterparse(filename, events=("start", "end", "start-ns"))

cara kedua menghasilkan objek iterator yang jika dimasukkan dalam konstruk for menghasilkan 2-tuple action dan current tag.

for action, el in ctx:
        if action == "start-ns":
            print el[0], el[1]
        elif action == "start":
            print el.tag
        elif action == "end":
            pass

Menggunakan RDFLib
RDFLib merupakan pustaka untuk memanipulasi data RDF yang berbentuk 3-tuple (subjek, predikat, objek). Satu triple RDF merupakan graf yang terdiri dari 2 simpul (subjek dan objek) dan 1 busur (predikat). Kumpulan RDF membentuk koleksi data sebagai graf yang lebih kompleks. Kumpulan data yang saling terhubung tetapi tersebar dalam web disebut sebagai Semantic Web/Linked Data. Untuk menggunakan RDFLib saya biasanya menggunakan 2 baris berikut di awal program.

from rdflib import ConjunctiveGraph, Namespace, exceptions
from rdflib import URIRef, RDFS, RDF, OWL, BNode, Literal

kelas utama yang dibutuhkan adalah ConjunctiveGraph. Data triple dapat disimpan dalam memori (default), atau disimpan dalam basis data relasional (SQLite, MySQL, PostgreSQL) ataupun penyimpanan lain (kyotocabinet) melalui sistem plugin.

Pernyataan sesuatu adalah owl:Class seperti dalam kaidah konversi di atas dilakukan dengan cara membuat tuple berisi 3 elemen (URIRef/BNode/Literal). RDF, RDFS, dan OWL merupakan kelas pembantu (helper) yang mendefinisikan URIRef untuk ontologi2 umum.

g = ConjunctiveGraph()
NS = Namespace("http://pebbie.net/semweb/")
g.bind(None, NS)
g.add( (NS["Tokoh"], RDF.type, OWL.Class) )
g.add( (NS["Nama"], RDF.type, OWL.DatatypeProperty) )
g.add( (NS["Nama"], RDFS.domain, NS["Tokoh"]) )
g.add( (NS["peb"], RDF.type, NS["Tokoh"]) )
g.add( (NS["peb"], NS["Nama"], Literal("Peb Ruswono Aryan")) )
g.serialize("contoh.ttl", format="turtle")

Sepotong kode di atas akan menghasilkan dokumen contoh.ttl dalam format turtle berisi:

@prefix : <http://pebbie.net/semweb/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

:Nama a <http://www.w3.org/2002/07/owl#DatatypeProperty> ;
    rdfs:domain :Tokoh .

:peb a :Tokoh ;
    :Nama "Peb Ruswono Aryan" .

:Tokoh a <http://www.w3.org/2002/07/owl#Class> .

Akhir kata, mari kita tutup pengajian kita dengan membaca kode utama

Tinggalkan Balasan

Isikan data di bawah atau klik salah satu ikon untuk log in:

Logo WordPress.com

You are commenting using your WordPress.com account. Logout / Ubah )

Gambar Twitter

You are commenting using your Twitter account. Logout / Ubah )

Foto Facebook

You are commenting using your Facebook account. Logout / Ubah )

Foto Google+

You are commenting using your Google+ account. Logout / Ubah )

Connecting to %s