XML’nin, herhangi bir uygulama için verinin içeriğini ve uygulamanın içerdiği veri tiplerini tanımlayacak özel bir işaretleme dili oluşturulabilen bir meta işaretleme dili olduğunu XML Nedir? Neden ve Nasıl Kullanılır? Her Yönüyle XML Rehberi yazısında değinmiştik. Bu yazıda XML DTD (document type definition – belge türü tanımı) konusuna giriş yaparak oluşturulan yeni işaretleme dillerinin genel olarak belirli kurallar çerçevesinde nasıl olacağını göreceğiz. Peki DTD nedir?
XML DTD Nedir? Ne İçin Kullanılır?
Document Type Definition (Belge Türü Tanımı) ifadesinin kısaltması olan DTD, XML belgesinin genel yapısını açıklayan bildirimlerdir. Bu bildirimlere uygun olarak hazırlanan XML belgesi valid yani geçerli belgelerdir. DTD SGML kökenlidir yani söz dizimi SGML’den gelmektedir.
XML tabanlı işaretleme dilleri kullanım amaçlarına göre ve uygulamanın kapsamına göre hazırlanır. Yani her XML belgesi uygulamaya özel bir şekilde oluşturulur. Tüm XML belgelerinin ortak yönleri olmasına rağmen uygulamaya özel belgeler yapısal olarak değişiklik gösterir. Örneğin bir XML belgesinin <adres> öğesine sahip olduğunu ve bu <adres> öğesinin de <sehir> alt öğesi olduğunu düşünelim. Tam burada bunu kullananlar için <adres> altında <sehir> alt öğesini de kullanması gerektiğini belirtebiliriz. İşte DTD (document type definition – belge türü tanımı) bildirim (declaration) olarak kullanıldığı takdirde bu alt öğe hakkında bilgilendirme yapılabilir ve bu alt öğe ile ilgili kural belirtilebilir.
DTD’nin neden kullanıldığını biraz daha açalım. Oluşturduğumuz bir XML belgesinde istediğimiz isimde ve istediğimiz sırada öğeler bulunabilir, öğelerin içerisinde istediğimiz kadar alt öğeler bulunabilir, öğelere istediğimiz gibi öznitelik (attribute) ve değeri verilebilir yani XML’nin bileşenleri serbest olarak kullanılabilir. Ancak XML tabanlı uygulamalarda öğeler rastgele sıradaysa ya da beklenmedik bir alandan dolayı bazı çakışmalar mevcutsa uygulama XML belgesini işleyemez. XML belgesinin işlenebilmesi için bazı yapısal ve içerikle ilgili kurallara bağlı kalmak gerekir. İşte DTD ile bu kurallar XML belgesinde sağlanabilir.
Özetle DTD sayesinde XML belgemizin formatının nasıl olacağını kendimiz belirleyebiliriz. GML, SGML, HTML ve tabi ki XML’de bildirim (declaration) olarak kullanılan DTD, belge içeriği ile ilgili kuralları belirtmenin iki yolundan biridir.
Diğer yol schema’yı XML Schema (XML Şeması) yazımızda inceleyebilirsiniz. XML Schema ve DTD arasındaki farkları da aynı şekilde bu yazıda inceleyebilirsiniz.
Geçerli Belge (Valid Document)
Belgeler, dilin tüm kurallarına uyduklarından emin olmak için bir DTD’ye karşı doğrulanabilir. DTD’yi karşılayan bir belge geçerli (valid) olarak adlandırılır. Yani eğer bir XML belgesi bir DTD’ye bağlı kural sağlayabiliyorsa geçerli (valid) bir belgedir.
XML, XML Dosyası ve XML Söz Dizimi Kuralları yazısında da gördüğümüz üzere yerine getirilmesi gereken bir dizi genel sözdizimi kuralı sağlar ve bir belge bu kuralları karşıladığı sürece, iyi biçimlendirilmiş belge (well formed document) olarak adlandırılır. Tüm geçerli belgeler de (valid documents) iyi biçimlendirilmiş olmalıdır.
DTD Bildirimi (Declaration)
DTD’nin yapısına giriş yapmadan önce bildirim (declaration) konusunu tekrar ele alalım. Bir XML belgesinin başlangıcında kök öğeden önce yer alan her şey prolog olarak kabul edilir. Yani prologta bildirim (declaration) yapılır. Prolog olarak XML bildirimi, belge türü bildirimi (document type declaration), işlem talimatları veya yorumlar bulunur (bu durumda XML bildiriminin her zaman belgenin en başında prolog olarak yer aldığını tekrar belirtmiş oluyoruz.) Dolayısıyla bir XML’de DTD’nin olması onun bir bildirim olduğu anlamına gelmektedir. DTD kullanılarak yapılan bildirime document type declaration ya da DOCTYPE denir. Başlangıçta DTD hakkında daha iyi fikir edinebilmek için örnek olarak W3C XML Specification DTD adresindeki dokümana göz atabilirsiniz.
DTD’nin Yapısı
DTD, XML ile oluşturulmuş bir dilin veya belgenin içermesine izin verildiği tüm bileşenleri ve bu bileşenler arasındaki yapısal ilişkileri tanımlar. DTD’de Bir XML belgesinde DTD ile verilecek bildirimler direkt belgenin içerisinde ise internal olarak, bildirimler ayrı dosyada tutuluyorsa external olarak isimlendirilir ve dosyanın formatı “.dtd” şeklindedir. Bildirimler aynı anda hem internal hem external olarak verilebilir.
Peki, bir XML belgesinin sınırlarını bazı kurallarla belirlemek için DTD’yi nasıl oluşturabiliriz? Yani nasıl bir belge türü tanımlayabiliriz? DTD’de 4 tane bildirim bulunmaktadır: ELEMENT, ATTLIST, ENTITY ve NOTATION. Bunların birer DTD bildirimi olduğunu sağlamak için öğelerin başında her zaman ! (Ünlem işareti bulunur.) Bunları şimdi teker teker görelim:
- Öğe Türü Bildirimi (ELEMENT): Bu bildirimler herhangi bir öğe (element) türü belirleyemeyiz. İzin verilen türlerin DTD ile bildirilmiş olması gerekir.
- Öznitelik Bildirimi (ATTLIST): DTD her öğenin başlangıç etiketine eklenebilecek öznitelik (attribute) kümesini sağlar (zaten XML’de öznitelikler öğelerin her zaman başlangıç etiketindedir.)
- Varlık Bildirimi (ENTITY): DTD’ler, genel varlıklar ve parametre varlıkları için belirtilen adı ve tanımları içerir. Varlıklar genellikle iç alt kümelerde (yakında tanımlayacağımız) ve dış alt kümelerde bildirilir. Varlıklar ayrı bir dosyada tanımlandığı kadar direkt XML belgesinin içerisinde de internal olarak bildirilebilir.
- Notasyon Bildirimi (NOTATION): Notasyon bildirimi, parse edilmemiş çeşitli binary verileri (ve bazen de metinleri) belirten etiketlerdir.
Bunların yanısıra DTD’de boşluk karakteri veya yorum da bulunabilir.
XML DTD Nasıl Oluşturulur? DTD Söz Dizimi
DTD karmaşık gibi görünse de aslında söz dizimi (syntax) basittir. Söz dizimi kurallarını inceledikten sonra size de DTD’lerin içeriği daha anlaşılır olacaktır.DTD, XML belgesinin içerisine gömülerek, ayrı bir DTD dosyası referans verilerek veya her ikisinin de olacağı şekilde belirtilerek kullanılabilir:
- XML dokümanının içerisine gömülürse DTD kuralları köşeli parantez içerisine [ … ] alınır:
<!DOCTYPE kok_oge [ <!ELEMENT merhaba (#PCDATA)>]>
- Harici bir dtd dosyası olarak kendi DTD’mizi yazarken yani XML belgesini bir uygulama işlemeyecekse yani private ise “Sytem” anahtar kelimelerini kullanarak yazabiliriz:
<!DOCTYPE kok_oge SYSTEM “DTD_veya_Bulundugu_Tam_URL”>
- Harici bir dtd dosyasını bir editör ya da bir uygulama biliyorsa “PUBLIC” anahtar kelimesi kullanılır:
<!DOCTYPE kok_oge PUBLIC “DTD_adi” “DTD_veya_Bulundugu_Tam_URL”>
Örnek:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
Görüldüğü üzere DTD tanımı her zaman <!DOCTYPE ile başlıyor. DTD’de XML belgesinin formatının hangi çerçevede olacağını belirtmek için DTD’nin yapısı ve söz dizimi nasıl olmalıdır, bildirimleri ayrı ayrı inceleyelim.
Öğelerin Bildirimi
- Genel Söz Dizimi Nasıl Olmalı: <!ELEMENT etiket_adi (alt_oge_belirtimi)>
Örnek: <!ELEMENT ileti (ad, eposta+, konu, kategori, mesaj)>
- #PCDATA: “Parsed Character Data” ifadesinin kısaltılmış halidir. Bir öğe sadece metin içeriyorsa ve alt öğeleri yoksa bu anahtar kelime kullanılır. Yani <,>,&,’ ve ” karakterlerinin olmadığı işlenebilecek metnin olduğu öğeler için kullanılır.
Örnek: <!ELEMENT ad (#PCDATA)><!ELEMENT eposta (#PCDATA)><!ELEMENT konu (#PCDATA)><!ELEMENT kategori (#PCDATA)>
- ANY: Hiç belirtilmemiş alt öğeler ve “parsed character data”lara izin verir. Bu anahtar kelimenin kullanılması önerilmez.
- EMPTY: Eğer bir öğe içeriği boş ise bu anahtar kelime kullanılır.
Örnek: <!ELEMENT br EMPTY>
Öğeleri bu şekilde tanımlarken belirli kombinasyonlarla zenginleştirme yapılabilir. Bu kurallar da şu şekildedir:
A ve B Etiketleri | Açıklama |
A, B | A’yı B takip eder. |
A? | A opsiyoneldir. A kullanılabilir de kullanılmayabilir de. |
A+ | En az 1 tane A olmalıdır. |
A* | A 0, 1 veya 1’den çok olabilir. |
A|B | A ya da B’nin ikisinden biri olmalıdır. |
(A,B) | Parantez ile gruplama yapabilir. |
Bildirimlerde “,” verilen sırada oluşacağını söyler, “|” işareti de öğelerden sadece birinin oluşacağını söyler.
Öznitelik (Attribute) Bildirimi
- Genel Söz Dizimi Nasıl Olmalı: <!ATTLIST oge_adi öznitelik_adi Oznitelik_turu Tur_Tanimi Default >
Söz diziminde belirtilen öznitelik türü ve öznitelik tanımları şu şekildedir:
Öznitelik Operasyonları | Açıklama |
CDATA | “Character Data” parse edilmeyen metin verisi. Yani içerikte işaretleme veya entity varsa bunlar sadece metin olarak değerlendirilecektir. |
A? | A opsiyoneldir. A kullanılabilir de kullanılmayabilir de. |
A+ | En az 1 tane A olmalıdır. |
A* | A 0, 1 veya 1’den çok olabilir. |
A|B | A ya da B’nin ikisinden biri olmalıdır. |
(A,B) | Parantez ile gruplama yapabilir. |
Öznitelik Parametre | Açıklama |
#IMPLIED | Öznitelik opsiyoneldir. |
#REQUIRED | Öznitelik zorunludur. |
#FIXED Değer | Öznitelik sabit bir değere sahiptir, o da bu anahtar kelimeden sonra belirtilen “Değer”dir. Kullanıcı bunu değiştiremez. |
Örnekler: <!ATTLIST ogrenci ad CDATA #REQUIRED> <ogrenci ad=”Ahmet”> <!ATTLIST ogrenci cinsiyet (m|f) #REQUIRED> <ogrenci cinsiyet=”m”> <!ATTLIST form method CDATA #FIXED “POST”> <form method=”POST”>
Bir öğenin birden fazla özniteliği olabileceği için bunları ayrı ayrı tanımlamak yerine tek bir tanımla da belirtebiliriz.
Örnek:
<!ATTLIST öğrenci
ident ID #REQUIRED
ad (male|female) #IMPLIED
cinsiyet (m|f) #REQUIRED >
Varlık (Entity) Bildirimi
Varlıkları diğer bazı içeriklerin kısaltmaları olarak düşümebiliriz. Bir varlık DTD’de tanımlandıktan sonra içeriği XML dosyasında karşılaşıldığında değiştirilir. XML başlangıçta yalnızca 5 varlığı tanımlarken HTML daha fazlasını yapar.
- Genel Söz Dizimi Nasıl Olmalı: <!ENTITY varlik_adi içerik(veya URL)>
- Tanımlanan Bir Varlığın Kullanımı Nasıl Olmalı: &varlik_adi;
Örnek:
<!ENTITY xd “XML DTD”> olarak bir varlık tanımladığımızı varsayalım. XML’de bunu <oge> &xd; nedir?</oge> olacak şekilde kullanırız. İşte bunun çıktısı da <oge>XML DTD nedir?</oge> olacaktır.
Karmaşık DTD’lerde genel olarak parametrik varlıklar kullanılır. Parametrik olması için varlık adının öncesinde % işareti konulur. Yani söz dizimi şu şekildedir: <!ENTITY % varlik_adi içerik(veya URL)>
Örnek:
<!ENTITY % icerik “(Ev | Araba | Urun)*”> şeklinde bir parametrik varlık tanımlayalım. Bunu sonra DTD’de bazı öğeler için kullanalım:
<!ELEMENT satilik(baslik, %icerik; ) >
<!ELEMENT kiralik(baslik, %icerik; ) >
Aslında tanımladığımız bu öğelerin anlamı şudur:
<!ELEMENT satilik(baslik, (Ev | Araba | Urun)* ) >
<!ELEMENT kiralik(baslik, (Ev | Araba | Urun)* ) >
Bu özellik aynı şekilde öznitelik bildirimleri için de kullanılabilir.
Notasyon Bildirimi
DTD’de son olarak göreceğimiz bildirim notasyon bildirimidir. Notasyon aslında bir öznitelik türüdür. Notasyonlar parse edilmemiş varlıkları (entity) belirlemek için NOTATION anahtar kelimesi ile kullanılır. Kullanım amacı aslında desteklenen veri türünü bildirmektir. Yaygın olarak image/gif, image/jpeg gibi türleri tanımlamak için kullanılır.
- Genel Söz Dizimi Nasıl Olmalı: <!NOTATION isim SYSTEM “external_id”>
<!NOTATION name PUBLIC “public_ID”><!NOTATION name PUBLIC “public_ID” “URI”>
- Öznitelik bildiriminde kullanımı:
<!ATTLIST element_name
attribute_name NOTATION default_value>
Örnek:
<!NOTATION GIF SYSTEM “image/gif”>
<!NOTATION JPG SYSTEM “image/jpeg”>
<!NOTATION PNG SYSTEM “image/png”>
<!ATTLIST sehir
resim ENTITY #IMPLIED
resim_turu NOTATION (GIF | JPG | PNG) #IMPLIED>
<!ENTITY resim1 SYSTEM “resim1.jpg”>
XML’de bunu aşağıdaki gibi kullanabiliriz:
<sehirler>
<sehir resim=”resim1” resim_turu=”JPG”>İSTANBUL</sehir>
<sehir>ANKARA</sehir>
</sehirler>
Örnek Bir XML DTD
Bu bilgiler ışığında hazırladığımız XML belgesi içerisinde bildirimi yapılmış (internal) bir DTD örneği:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ileti [
<!ELEMENT ileti (ad,eposta, kategori, konu, mesaj, copyright)>
<!ELEMENT ad (#PCDATA)>
<!ELEMENT eposta (#PCDATA )>
<!ELEMENT kategori EMPTY>
<!ELEMENT konu (#PCDATA)>
<!ELEMENT mesaj (#PCDATA)>
<!ELEMENT copyright (#PCDATA)>
<!ENTITY copyright "Arakatman.com">
<!ATTLIST kategori tur (istek|talep|oneri|soru) #IMPLIED>
]>
<ileti>
<ad>Ahmet</ad>
<eposta>Ahmet@a.com</eposta>
<kategori tur="soru"></kategori>
<konu>XML DTD nedir?</konu>
<mesaj>XML DTD tam olarak nedir?</mesaj>
<copyright>Tüm hakkı ©right; a aittir! </copyright>
</ileti>
Tanımladığımız DTD sayesinde XML belgemiz artık istediğimiz formatta! Yukarıdaki örneği https://www.xmlvalidation.com/ adresine giderek valid olduğunu test ederek görebilirsiniz. Hatta üzerinde bazı değişiklikler yaparak hangi hataların verildiğini yani valid özelliğinin bozulduğunu görebilirsiniz. Bu konuyla ilgili daha detaylı bilgi için https://www.w3.org/TR/xml/ adresini ziyaret edebilirsiniz.
XML DTD ile İlgili Bazı Öneriler
»
Kullanılacak her öğeyi tanımlamayı unutmamak gerekir (kök öğenin de ayrıca tanımlandığına dikkat edin.)
»
DTD yazmaya başlamadan önce basit bir taslağını çıkarmak çok yararlı olacaktır.
»
Tasarımı tepeden aşağıya doğru kök öğeden başlayarak onun alt öğesine ve ne kadar alt öğe varsa sırayla yapın.
»
Herhangi bir konuyla ilgili, uygulamayla ilgili modelleyeceğiniz noktayı “öğe” olarak kullanın. Bu öğenin bir özelliği varsa bunu da attribute yani öznitelik olarak kullanın.
»
Sıralama önemli ise öznitelik yerine öğe kullanın (öznitelikler sıralanamaz.)
»
Belli bir veri kümesi daha anlamlı olacaksa bunları öğe olarak tanımlayın.
»
Başka bir öğeye referans verilmesi gerekiyorsa ya da öğenin türünü kullanımını bildirmek gerekiyorsa bunu öznitelikle yapın.
»
Veriyle ilgili bazı kısıtlamalar yapılması gerekiyorsa ya da kullanıcıya girilebilecek olası tüm değerleri listelemek için öznitelik kullanın.
»
<, & ,> ,” ve ’ karakterlerinin belge içerisinde kullanılması gerekiyorsa aşağıdaki string karşılıklarını kullanabilirsiniz. XML belgesinde bu karakterleri direkt kullandığınız takdirde belge işlenirken / parse edilirken hata verecektir:
Char | String |
< | < |
> | > |
“ | " |
‘ | ' |
& | & |