XML nedir? XML nedir? XML (Genişletilebilir İşaretleme Dili) web in işlevselliğini geliştirmek için dizayn edilmiş esnek ve uygulanabilir bilgi tanımlama dilidir.HTML gibi statik ve önceden tanımlanmış bir forma sahip olmayan XML , diğer dillerin tanımlanabildiği bir meta-dildir.Bu sayede değişik tipte dokümanlar için kendi işaretleme dilinizi geliştirebilirsiniz. XML ne için kullanılır XML , SGML in web üzrinde kolayca kullanılması için geliştirilmiştir.Doküman türlerinin kolayca tanımlanmasında , SGML tanımlı dokümanların kolay yönetimi ve yazımı ve web üzerinden kolay transferi için bulunmaktadır. XML herhangi yapısal bilginin saklanmasında ve farklı işleme ortamlarında bilginin transferinin mümkün olmadığı koşullarda bilginin evrensel yapılandırılması için kullanılmaktadır. SGML nedir? SGML farklı türdeki ve standarddır(ISO8879:1985).
yapıdaki
dokümanların
tanımlanması
için
kullanılan
uluslarası
bir
SGML , insan aktivitelerinin bulunduğu tüm farklı doküman türlerinde gerçek konuşma dili ile yazılmış , eski Mısır dilindeki inşaa tanımlarından günümüzdeki hayalet uçak teknik dokümantasyonuna; bir hastanın klinik raporundan bir müziğin notasına kadar doküman içeriğinin belirlenmesinde kullanılmaktadır. SGML çok büyük,güçlü ve karmaşıktır.Son yıllarda endüstriyel ve ticari kullanımda olmasına karşın SGML kullanımı uzmanlık ve kendisini kullanabilecek programların detaylı olmasını gerektirmektedir.XML , SGML in küçültülmüş bir versiyonu olmakla beraber web ortamında implemente edilmesi çok zor olan SGML özelliklerini ortadan kaldırmıştır. SGML i doküman tanımlamak için izleyen ilk işaretleme dili HTML olmuştur.Basit yapısı , HTML in çok popular hale gelmesine yol açmış ve bu sayede HTML , web in temelini oluşturmaya başlamıştır. HTML yi izleyen ve bilginin temsil edilmesi için farklı doküman tanımlama ve veri yapısı oluşturma metodolojisi , HTML in bu çok basit yapısının yetersizliğinden kaynaklanmaktadır. HTML yi izleyen yıllarda Java ve Javascriptin uygulamaları , sunucu taraflı dinamik HTML sayfaları oluşturan CGI programları ve CSS ve DHTML gibi teknolojiler geliştirildi.Bu teknolojiler HTML in yeteneklerini geliştirmek için geliştirilmiş olsa da bu yöndeki sıkıntıyı daha da açığa çıkardılar. Sonuçta XML geliştirildi. XML Yapısı XML , yapısının tamamen kullanıcı tarafından oluşturulduğu ve verinin tanımı için DTD(Doküman Tipi Tanımı) yapıları ile içerisinde kullanılacak verinin ve yapısının yapıldığı işaretleme dilidir. Mesela günümüzde cep telefonlarında kullanılan WAP sayfalarının tanımları , XML meta dilinden türetilmiş olan WML dili ile yazılmaktadır. XML Kullanımı ve işleme XML in kullanımı için çok sayıda teknik bulunmaktadır.Buna bir giriş yapmak için XML veri adaları ile başlayalım. XML Veri Adaları , bir HTML sayfasında xml ile yapılan veri tanımının gömülü olması demektir.XML deklarasyonu <XML ID=’XXX’> Tanım …. şeklinde bir tek değer bağlayıcısı ile yapılarak daha sonra HTML belgeisi içerisinde XML tanımının tanımlayıcısı referans gösterilerek , HTML belgesinden XML verisinin kullanımı gerçekleştirilebilir. <XML ID = ‘XXX’ SRC=’XML dokümanının ismi’>
XML içeriğinde kullanılan elemanlar ve özelliklerinin kullanımlarından once tanımlanmış olmaları gerekmektedir. Ayrıca doğruluk denetimleri ve XML belgesinin bu doğruluk denetimlerine uygunluğu ve geçerlilik koşulları da bulunmaktadır. DTD(Doküman tipi tanımı) DTD , XML belgelerinde kullanılan elemanların uygulamadan uygulamaya fark gösterebilmesi nedeniyle önceden tanımlanması için kullanılan stamdarddır.DTD , XML dosyasının içerisinde ya da bulunduğu yerin adresinin belirtilmesi yolu ile harici olarak XML belgesi ile ilişkilendirilebilir.
<motor> Jet A130
Kullanılan herhangi bir XML Parser(XML Ayrıştırıcı) yukarıdaki gibi bir doküman ile karşılaştığında , tanımların belirlenen ucak.dtd içerisinde yapıldığını anlamaktadır. Yukarıdaki örneğin DTD tanımı izleyen şekilde yapılabilir.Bu tanımların oluşturulma yapıları daha sonar XML grameri bölümlerinde ayrıntılı bir şekilde işlenecektir. Yukarıda sözü geçen kavramların işlenmesi: İŞLEME XML Belgesi XML DTD Belgesi StyleSheet(CSS)
___________
XML PARSER
___________ ___________
StyleSheet İM
Şeklinde gerçekleştirilmektedir. XML Parser Modelleri XML birbirinden bağımsız uygulamalar arasında bir veri transferi standardı haline geldiğinden içerisinde belirtimi yapılan verinin içinden çekilip alınması gerekmektedir.XML Parse(Ayrştırma) etme işlemi , XML belgesinin içerisinden , onu kullanacak uygulamanın anlayacağı verinin üretilmesi işlemidir. Uygulamaların XML işleyicilerinden gelen bilgileri ele alabilmeleri üretilen uygulamanın üretimlesi ve oluşturtulan arayüz ile mümkündür.SAX(XML için Basit API) ve DOM(Doküman Nesne Modeli) bu iş için standarda bağlanmış arayüzler olmakla beraber farklı bir API a bağlı bir XML Parser da kullanılabilmektedir.Kullanılan API lar ağaç yapısı tabanlı ve event-drıven olarak iki yapıya sahiptirler. DOM standardında olduğu ilk türde XML belgesinde sunulan belgenin kök elemandan başlayarak bir ağaç yapısına dönüştürülmesi ve XML ile temsil edilen verinin uygulama tarafından kullanılması esnasında , bu ağaç yapısını kullanılması sağlanır. SAX API ve aynı yapıdaki diğer API tanımları ise parse işlemi sırasında karşılaşılan tüm olayları(event) anında uygulamaya bildirirler. Bu şekilde bir ağaç yapısına gerek kalmadığı gibi uygulama programları ortaya çıkabilecek olaylar karşısında ne yapmaları gerektiği ile ilgili event-handler tanımlarını kendileri belirtmel zorundadır. SAX SAX , W3C Konsorsiyomu dışında yer alan XML standardlarından birisidir. Zayıf sistemlerdeki hafıza kısıtlaması durumlarında çok büyük dokümanların parse işlemi bugün SAX ile gerçekleştirilmektedir. SAX prosesi izleyen şekildedir
XML Parser belgeyi taradığı sırada sonuçları SAX a gönderir ; bu esnada SAX dokümanda karşılaşılan her etiket tanımı için içsel olarak event ler oluşturur.Uygulama kendi içerisinde tanımlanan eventlere gore ele alma işlemini kendisi geröekleştirmektedir.İşlemlerin gerçekleştirilmesi ve XML Validasyonu uygulamanın kendisi tarafından yapıldığından tüm belgenin hafızaya yüklenmesi gerekmemektedir. Örnek:
Beygir SAX Parser yukarıdaki XML belgesinin parse edilmesi sırasında izleyen olayları oluşturmaktadır. startDocument startElement: otomobil startElement: guc characters: Beygir endElement: guc endElement: otomobil endDocument SAX istemci uygulaması ilgilendiği her olaya karşılık gelen bir servis sağlayarak belgeyi işleyebilir. DOM(Doküman Nesne Modeli) DOM modeli , W3C Konsorsiyomu tarafından kabul edilmiş olan doküman yapısı için bir API dır.Programcıların dokümanın bileşenlerini slime,ekleme,değiştirmesini kolaylaştıran bu yapı ayrıca özellik ve stil düzenlemede de oldukça yardımcı bir arayüzdür.DOM her türlü tarayıcı ve sunucuda ve tüm platformlarda çalışabilecek uygulamalar geliştirilmesini sağlamaktadır. DOM mimarisi herbiri belirli bir bölgeyi içeren birden çok mdüle bölünmüştür.DOM API tarafından içerilen bu bölümler XML,HTML,CSS ve ağaç yapılarını içermektedir.İleride içerilebilecek bölümler arasında giriş dokümanından farklılık gösterebilecek olan gösterim dokümanları ve kullanıcı fonksiyonları yer almaktadır. 1998 yılında çıkan ilk DOM versiyonu XML 1.0 ve HTML 4.0 ile uyumluluk göstermekte ve aşağıdaki mimariye sahipti.
İzleyen yıl 2000 yılın Kasım ayında DOM 2 spesifikasyonu sunulmuş ve XML 1.0 a isim uzayo desteği verilmiştir.Bunun yanısıra CSS desteği verilmiş ve birazdan tanımını vereceğimiz ağaç yağısı işleme mekanizmaları sunulmuştur.DOM 2 mimarisi aşağıdaki şekilde oluşturulmuştur.
DOM 3 bunların yazıldığı anda hala geliştirme aşamasında olmakla beraber DOM çekirdeği ile XML 1.0 isim uzayının XML Infoset ile desteğinin geliştirilmesi , XML Base desteğinin verilmesi ve kullanıcı arayüzü olaylarının genişletilmesi hedeflenmektedir.Seviye 3 ayrıca geçerleme desteğide sunacak , dokümanların kaydedilip yüklenmesini sağlayarak daha iyi bir dağarcık işaretlemesi sağlayacak ve XPath desteği(ağaç yapısındaki node’ların adreslenmesi) sunacaktır.Geliştirilmekte olan DOM 3 API izleyen mimariye sahiptir.
Bu modelde XML dokümanı , node (düğüm) lerden oluşmuş bir ağaç yapısına dönüştürülerek işlenilen birimin hafızasına alınmaktadır.XML dokümanında tanımlanan tüm yapı hafızada komple tutulduğundan , bu model çok büyük uygulamalar için hafıza kısıtlamaları getiren ve çoğu kez yavaş işlenen bir modeldir.
DOM yapıya ulaşım için arayüzler ve bu arayüzlerin içerisinde tanımlanmış olan node metod ve özellikleri içermektedir.DOM kullanan bir parser da istenen node a ulaşmak izleyen şekildeki gibidir. Örnek: <silahlar> <savasucagi>
F-16 1300km <savasucagi>
F-22 1620km Ulaşılması istenen node birinci hız değeri ise:
kullanılan metodlar doc.documentElement.childNodes.item(0).getElementsByTagName(“hiz”).item(0).childNodes.item( 0).data şeklindedir. Bu tanımın açılımı doc adındaki DOM nesnesinin doküman elementlerinin kök node undan ilk yaprağın seçilmesi buradan etiket ismi ile etiketin seçilmesi ve kendi ilk nodunun değerinin okunması sağlanmaktadır. Şimdi yukarıdaki yapıyı işleyen çok basit bir HTML DOM parser örneği verelim:
<TITLE>DOM Parser
DOM Ornegi
<SCRIPT LANGUAGE="JavaScript"> var doc, kok, silah1, tip, hiz; doc = new ActiveXObject("Microsoft.XMLDOM"); doc.async = false; doc.load("silahlar.xml"); if (doc.parseError != 0) alert(doc.parseError.reason); else { kok = doc.documentElement; document.write("Kok node un adi: " + kok.nodeName + "
"); document.write("Kok node un tipi: " + kok.nodeType + "
");
silah1 = kok.childNodes.item(0); tip = silah1.getElementsByTagName("tip"); document.write("Tip adedi: " + tip.length + "
"); hiz = tip.item(0); document.write("Hiz : " + hiz.childNodes.item(0).data); }
XML Parser XML Parser , yazı dizimizin başında da belirttiğim üzere bir XML belgesinin içeriğini ve oluşturulma kurallarını denetler.Belgenin iyi oluşturulmuş olup olmadığını denetlerken DTD tanımına uygunluğunu da control eder.XML Parser ın diğer bir görevi de , XML belgesinin validasyonudur. DOM ve SAX modelini destekleyen birçok XML Parser mevcuttur.Bunlardan Xerces,XJ,MSXML,Lark,XML4J,ProjectX ve J2EE uygulamaları için Weblogic Server in sundugu XML Parser lar en cok bilinenlerdendir. XML Schema XML Schema XML Schema DTD gıbı XML dokümanında bulunan elementlerin ve içerik modelinin tanımlanmasını ve dokümanın geçerlenmesi için kullanılmaktadır. XML Schema DTD ye göre daha gelişmiş bir tanımlama standardıdır çünkü DTD içerisinde herhangi bir elemanın içeriği için mevcut olan değerler oldukça sınırlı olmasına karşın XML Schema içerisinde oldukça geniş bir yelpaze mevcuttur.(integer,float,date … gibi).XML Schema açık içerik modeli tanımlamaları ve isim uzayı ek özellikleri ile de DTD den ayrılmaktadır. XML Schema nın en büyük özelliği tanımlama sırasında XML yapısını kullanmasıdır,böylece bir Schema tanımlaması XML de Schemaya özgü komutların kullanılması ile kolayca uygulanabilir. XML Schemalar aynen XML belgeleri gibi parse edilebilir özelliktedir.Schema içerisinde kullanılan açık-uçlu veri modeli , eleman ilişkilerinin geliştirilemsini ve geniş bir dağarcık belirtimi gibi destekler sağlar.İsim uzayı ek özelliği,schema içerisindeki ayrı node ların bir araya getirilmesini sağlamaktadır. XML Schema Yapı Özellikleri XML Schema DTD , Schema Element ve ElementType Element gibi iki önemli kavram içermektedir.Bu iki kavramın işlenmesi XML Schema DTD nin anlaşılması için yardımcı olacaktır. Schema Element Schema elemanı XML Schema belgeleri için kök eleman olarak adlandırılır ve diğer schema içeriği için bir taşıyıcı rolü üstlenmektedir.Schema elemanı name ve xmlns adlı iki özellik barındırmaktadır. Bunlarda name özelliği XML Schema ya verilecek olan isimdir.xmlns ise XML Schema için bir isim uzayı oluşturmak için kullanılmaktadır.Bu özellik kullanılacak schema belirtimlerinin kullanılması için gerekli olan belirtime sahip olmalıdır. Örneğin: <Schema name="Schema1" xmlns= urn:schemas-microsoft-com:xml-data"> <xmlns:dt= xmlns= urn:schemas-microsoft-com:xml-datatypes"> Microsoft un sağladığı schema belirtimlerini kullanabilmek için yazılan isim uzayına bir örnektir.
Peki isim uzayı nedir?İsim uzayları XML dokümanlarında kullanılan eleman ve eleman özelliklerinin tek isimlere (unique) sahip olmalarını sağlamaktadır. Bu tanımı izleyen satırda ise isim uzayının kullanacağı veri tipinin tanımı yapılmıştır.Bu örnekte Microsoft un sunduğu isim uzayı kullanılmaktadır.Bir Schema elemanı özellik tipi ve eleman tipi ve tanımları child eleman olarak içerebilmektedir. ElementType Element Schema elemanlarının tip belirtimi için Eleman Tipi Elemanlar kullanılmaktadır.Bu elemanın yapısında veri tipi,elaman,özellik tipi,özellik ve tanımchild elemanları bulunabilektedir. ElemanTipi eleman belirtiminde name elemanın ismini,model içerik belirtiminin kapalı yada açık olarak yapılacağını,content eleman içerisinde bulunan içeriğin tipini,order eleman içerisinde bulunan child elemanlarının ve gruplarının sırasını,ve son olarak dt:type elemanın tipini belirtmektedir.
SOAP(Basit Nesne Erişim Protokolü) SOAP SOAP şu anda ortaya çıkmış en son XML teknolojilerinden birisidir.SOAP internet uygulamalarında önceden beri süregelen bir problemi ortadan kaldırmak için geliştirilmiştir.Bu problem interoperability(sistemler arası uyumlu çalışma) problemidir.Sunucularda tüm nesne ve servislere platformdan bağımsız olarak ulaşım fikri bu protokolün gelişmesine yol açmıştır.Bugün varolan sistemlerin yapısında birbirinden farklı işletim sistemleri,firewall’lar,değişik uzaktan prosedür çağrı metodları ve farklı platformlar bulunmaktadır. İnternet üzerinde böylesi farklı sistemlerde karşılıklı çalışabilmek için sunucu ve istemci mimarilerinin birbirlerinin güvenlik kısıtlamalarını , servis konuşlandırım şemalarını ve aynı platform dilini kullanabilmeleri gerekmektedir.(COM—COM , ORB – ORB , EJB – EJB gıbı). SOAP ile yaşanılan bu platform karmaşasına son verilmiştir.IETF HTTP ve W3C konsorsiyomu XML standardlarına dayalı olan SOAP , birbirleriyle rekabet halinde olan nesne RPC (uzaktan prosedür çağrıları) teknolojileri arasında bir köprü oluşturmakta ve herhangi bir işletim sistemi,programlama dili veya platform ile çalışacak bir mesaj sistemi içermektedir. Basitçe belirtmek gerekirse , SOAP servislere , nesnelere ve sunuculara platformdan bağımsız bir şekilde erişmek için bir yol belirtimi yapmaktadır.SOAP kullanarak servis sorguları,çağrılar,iletişimi uzaktaki sistemin platformu,yeri ve işletim sisteminden bağımsız bir şekilde gerçekleştirmenizin yolu açılmış olmaktadır. SDL (Servis Tanımlama Dili) Uzaktaki bir sunucuda bulunan bir servisi SOAP kullanarak kullanmak istediğinizde, sizing (uygulamanızın) servisin yapabileceklerini anlamanız gerekmektedir.Unutulmamalıdır ki servisin işlevinin anlaşılması ile servisin implemantasyonunun anlaşılması; ki bu platform bağımlı bir tanımdır; birbirinden kesinlikle ayrılması gerekmektedir.SDL kullanımı , uzaktaki servise bir sorgu gönderilmesini ve yapabileceklerinin öğrenilmesini sağlamaktadır.(Veri Tipleri ve komutları nasıl temsil ettiği gibi)Mesela SDL kullanılarak basit bir servisin girdi olarak iki tamsayı alıp bu sayıları topladığı ve çıktı olarak yine bir tamsayı döndürdüğü rahatlıkla anlaşılabilir. SDL bir XML grameridir , yani basitçe bir XML dokümanıdır.SDL , aryüz belirtim dili olan IDL ye çok benzemektedir , aralarındaki fark ise IDL nin platform bağımlı SDL nin ise bağımsız olmasıdır. SCL (SOAP Kontrat Dili) SDL gibi SOAP Kontrat Dili bir servisin yapabileceklerinin ortaya çıkarılması için geliştirilmiştir fakat SCL bundan daha da öteye giderek sunucu ve istemcinin hangi iletişim anlaşmalarını kullanacaklarını belirlemektedir.Bu anlaşma hem uç noktaların tanımları ve kabul edebileceği mesajı içermekte hem de iki taraf arasında akan mesajların senkronizasyon kurallarını belirlemektedir. DISCO (Web Servislerinin Keşfi) DISCO erişilen makinelerdeki servislerin SDL veya SCL tanımlarını almak için bir yol sunmaktadır.Bu SOAP un herşeyi birleştirmek için kullanılan son parçasıdır.Keşif Doküman Düzeni Kullanılarak(Kendisi de bir XML dokümanıdır) keşif dokümanı sunucuya gönderilebilir ve sunucuda herhangi SOAP izinli bir AKA servisi bulunur ise sunulan servislerin bir SDL veya SCL tanımları elde edilmiş olmaktadır. ROPE (Uzak Nesne Proxy Motoru)
ROPE , uygulamalarınızda SOAP mesajlarını kullanabilmeniz için size COM bileşenlerini sunmaktadır. Rope.dll şeklindeki kütüphane dosyaları ile gelen ROPE bileşenleri iki modele sahiptir; VB – biçimli basitlik ve VC – biçimli control.. ROPE kullanmadan bir SOAP metodu çağırmak isterseniz tüm SOAP çağrılarını XML e uyarlamanız , çağrıyı bir HTTP isteği içerisine paketleyip göndermeniz ve HTTP cevabını işleyip gelen XML i parse etme işlemlerini gerçekleştirmeniz gerekmektedir.ROPE sayılan tüm bu işlemleri gerçekleştirmektedir.ROPE SOAP için işleri kolaylaştırıcı bir araç gibi düşünülebilir ancak SOAP kullanımı için zorunlu değildir. Visual Studio 6.0 için Microsoft tarafından geliştirilen SOAP araçkiti XML ve SOAP uzmanı olmanız gerekmemekte ve wire protokolü bilginizin olması şart değildir kolaylıkla uygulamanıza SOAP yeteneklerinin eklenmesi düşünülmektedir. Araç kitinde • Sunucu taraflı referans dinleyicileri • ROPE • SDL ve kaynak kodu jeneratörü • Dokümentasyon • Kod örnekleri
•
Ve Mimari Model ve tüm kaynak kodu Bulunmaktadır. XML Grameri
- Bölüm 1
Giriş Genişletilebilir İşaretleme Dili(Extensible Markup Language) , kısaca XML , XML dokümanları adı verilen veri objeleri sınıfını tanımlayan ve kendisini işleyen porgramların davranışlarını tanımlayan bir işaretleme dilidir. XML dokümanları entity(varlık) adı verilen saklama birimlerinden luşmaktadır ve bunlar parse edilmiş veya edilmemiş veri barındırabilirler. Başlangıç ve hedefler XML 1996 yılında World Wide Web konsorsiyumu altında oluşturulan XML Çalışma Grubu tarafından geliştirildi. XML in dizayn hedefleri 1.İnternette basitçe kullanabilmesi 2.XML in geniş yelpazede uygulamaları desteklemesi 3.XML in SGML(Standard Generalized Markup Language) ile uyumlu olabilmesi 4.XML dokünmanlarını işleyen programların kolaylıkla yazılabilmesi 5.XML e ait ek opsiyonel özelliklerin sıfır denecek kadar az seviyede tutulması 6.XML dokümanlarının insanlar tarafından anlaşılabilir düzeyde ve açık olması 7.XML dizaynının çok hızlı bir biçimde oluşturulabilmesi 8.XML in dizaynının formal ve işe özgü yapılabilmesi 9.XML dokümanları oluşturmanın çok basit olması şeklinde listelenebilir. Dokümanlar Bir veri objesi eğer iyi oluşturulmuş(well-formed) ve bu spesifikasyon ile tanımlanmış ise bir XML dokümanı olarak adlandırılır.Eğer gereken kısıtlamaları da karşılıyor ise XML dokümanı için geçerli(valid) adı verilebilir Her XML dokümanının mantıksal ve fiziksel yapıları bulunmaktadır.Fiziksel olarak,doküman varlık adı verilen birimlerden oluşmaktadır.Bir varlık doküman içerisinde diğer varlıkları ihtiva edebilmektedir.Bir doküman bir kök(root) veya doküman varlığı ile başlamaktadır.Mantıksal olarak , doküman tanımlar , elementler , yorumlar , karakter referansları , ve işleme komutlarından oluşmaktadır.Bunların hepsi doküman içerisinde işaretleme ile belirtilir.
İyi oluşturulmuş XML Dokümanları Bir metin objesinin iyi oluşturulmuş bir XML dokümanı olabilmesi için: 1.Bütün olarak , üretim etiketli doküman ile uyuşması
2.Bu spesifikasyonda verilen tüm iyi oluşturulma kısıtlamalarına uyması 3.Her parse edilmiş varlığının doküman içerisinde direkt veya indirekt olarak gerekmektedir.
referans
edilmesi
XML dokümanlarında işaretleme için metinler karakterlerden oluşturulmaktadır.Karakterler ISO veya standardı ile beilrtilebilmektedirler.Karakter kod noktası çözümleme mekanizması varlıktan varlığa göre değişim gösterebilmektedir.Tüm XML işleyiciler UTF-8 ve UTF-16 encoding standardlarını kabul etmelidirler. Genel syntax kuralları
Boşluk Grameri S ::= (#x20 OR #x9 OR #xD OR #xA)+
şeklinde tanımlanmıştır Bu gramerde boşluk karakterleri XML tanımlarında bir veya daha vazla boşluk (space) , yeni satır başlangıçları , çizgi beslemeleri(line feed) , veya tab lardan oluşmaktadır İsimler Bir isim , XML de bir harf veya bir kaç noktalam işareti ile başlayan ve harf , sayı , altçizgi ... vb karakterler ile başlayan bileşenlere verilen addır.
İsimler ve Bileşenler(Token) Grameri [4] [5] [6] [7] [8]
NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender Name ::= (Letter | '_' | ':') (NameChar)* Names ::= Name (S Name)* Nmtoken ::= (NameChar)+ Nmtokens ::= Nmtoken (S Nmtoken
Literal verisi tırnak içerisine alınmış verilere verilen adlardır.Literaller iç verilerin , özelliklerin değerlerinin , ve dış belirteçlerin içeriklerini belirtmek için kullanılırlar.
Literal grameri [9] EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' | "'" ([^%&'] | PEReference | Reference)* "'" [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'" [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'") [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
Yorumlar Yorumlar XML dokümanlarının arasına işleyici program yada programcı tarafından konulan açıklayıcı terimlere verilen addır.
Yorum Grameri [15] Yorum ::= ''
XML Grameri
- Bölüm 2 -
İşleme Komutları İşleme komutları dokümanların uygulamalara gerekli olan komutları barındırmalarını sağlar. İşleme Komutları Grameri [16] PI ::= '' PITarget (S (Char* - (Char* '?>' Char*)))? '?>' [17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
İşleme komutları dokümanın karakter verisinin içerisinde yer almaz ancak uygulamaya geçirilmek için bulunmaktadırlar.İK tanımı bir hedef(PITarget) ile başlar ve bu komutun yönlendirildiği uygulamayı belirtmektedir.Hedef isimleri olarak "XML" , "xml" ve benzerleri bu işlemde standardizasyon için rezerve edilmişlerdir. CDATA bölümleri CDATA bölümleri karakter verisinin bulunduğu herhangi bir yerde bulunabilirler.CDATA bölümleri metin bulunduran karakterlerin escape olarak tanımlanmasında kullanılmaktadırlar.CDATA bölümleri "" ile biterler.
CDATA Bölüm grameri [18] [19] [20] [21]
CDSect ::= CDStart CData CDEnd CDStart ::= '' Char*)) CDEnd ::= ']]>'
CDATA bölümleri içerisinde sadece CDEnd cümlesi işaretleme olarak algılanmaktadır yani sol parantez ve ampersandlar kendi literal formlarında bulunabilmektedirler;< ve & gibi tanımlamalar ile belirtilemelerine gerek ve imkan yoktur. UYARI:
CDATA bölümleri yuvalı olarak tanımlanamazlar
Örnek: Hello, world!]]> burada greeting sadece bir metindir. Prolog ve Doküman Türü Tanımlar(Document Type Declarations(DTD)) XML dokümanları , kullanılan XML versiyonunu tanımlayan bir XML tanımı ile başlamak zorundadırlar.Mesela ızleyen XML dokümanı , iyi oluşturulmuş ancak geçerli olmayan bir XML dokümanıdır.
Hello, world! Versiyon numarası 1.0 , bu spesifikasyonun versiyonuna dokümanın uyumluluğunu göstermek için kullanılmalıdır , ancak bu spesifikasyon ile uyuşmayan bir dokümana bu değeri vermek hata teşkil etmektedir.İleriki versiyonlar belirtilmediğinden bu yapı , otomatik versiyon tanımlamasının gerekliliğine yol açmıştır.Bu sebepten işleyiciler kendilerinin desteklemediği versiyon etiketleri gördüklerinde hata mesajı verebilirler.XML dokümanları içerisinde işaretlemenin fonksiyonu saklama ve mantıksal yapının tanımı ve ayrıca özellik - değer ikililerinin mantıksal yapılarının tanımını yapmaktır.XML , DTD adı verilen mekanizma ile mantıksal yapı üzerinde kısıtlamalar belirtir ve önceden tanımlanmış saklama birimlerini destekler. Bir XML dokümanı , eğer ilişkili bir DTD barındırıyor ve doküman bu tanımdaki kısıtlamalara uyuyor ise geçerlidir.DTD tanımı dokümanda ilk elementten önce belirtilmelidir.
Prolog grameri [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? [23] XMLDecl ::= '' [24] VersionInfo ::= S 'version' Eq (' VersionNum ' | " VersionNum ")
[25] Eq ::= S? '=' S? [26] VersionNum ::= ([a-zA-Z0-9_.:] | '-')+ [27] Misc ::= Comment | PI | S
XML DTD , doküman sınıfları için gramer oluşturan işaretleme tanımlarını barındırmaktadır.DTD , işaretleme tanımları barındıran dış altkümelere (özel tip dış varlıklar) referans çıkarabilir.Bir işaretleme tanımı element tipi tanımları , özellik listesi tanımları , ve varlık(gösterim) tanımlarından oluşmaktadırlar.Bu tanımların bir kısmı yada tümü parametre varlıklarının içerisinde bulunabilirler.
DTD Grameri [28] doctypedecl ::= '' [ VC: Root Element Type ] [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment [ VC: Proper Declaration/PE Nesting ] [ WFC: PEs in Internal Subset ]
Geçerlilik Kısıtlaması 1: Kök element tipi DTD tanmındaki isim kök elemtin tipine uymalıdır Geçerlilik Kısıtlaması 2: Uygun tanım/Parametre Varlığı Yuvalaması Parametre - varlık yer değiştirme metni işaretleme tanımlarında uygun şekilde yerleştirilmelidir. İyi oluşturulma Kısıtlaması: Parametre/Varlıklar İç Kümede olmalıdır.DTD altkümesinde PV referansları işaretleme tanımlarının içerisinde değil sadece işaretleme tanımları varolduğunda olabilirler.
XML Grameri
- Bölüm 3 -
Yalnız Doküman Deklarasyonu(Standalone Document Declaration(SDD)) İşaretleme tanımları XML işleyiciden bir uygulamaya geçmek gibi dokümanın içeriğini etkileyebilmektedir.SDD,XML tanımının bir bileşeni gibi ortaya çıkabilmekte ve bu çeşit tanımlarının var olup olmadığını belirtebilmektedir.
Standalone Document Declaration Grameri [32] SDDecl ::= S 'standalone' Eq (("'" ('yes' | 'no') "'") | ('"' ('yes' | 'no') '"')) Standalone Document Declaration ]
[
VC:
SDD tanımında "yes" değeri doküman varlığının dışında bulunan ve XML işleyiciden uygulamaya geöen bilgiyi etkileyen işaretleme tanımlarının bulunmadığını göstermektedir."no" değeri ise bu gibi dış tanımların olabileceğini göstermektedir.Unutmayın ki bu yalnızlık durumunu değiştirme yeteneğine sahip değildir. Eğer dış tanımlar yoksa , SDD nin bir anlamı yoktur.Eğer dokümanlar varsa ve SDD tanımı yapılmamışsa bu değer "no" olarak varsayılmaktadır. Geçerlilik Kısıtlaması: Eğer dış • • • •
işaretleme tanımları: varsayılan değerlerde özellikler varlıklar normalizayon değerlerinde özellikler element içeriği tipleri
barındırıyorlarsa SDD değeri "no" olmalıdır
Bir SDD tanımlı XML dokümanı örneği aşağıdaki şekildedir.
Boşluklar XML dokümanları yazılırken boşluk ve tab boşlukları kullanılması okunabilirlik açısından uygun olacaktır.Bir XML işleyici işaretleme olmayan tüm karakterleri uygulama içerisinde geçmelidir.XML işleyici geçerleyicisi ayrıca element içeriğinde bulunan tüm böyle karakterleri uygulamaya bildirmelidir.xml:space adında özel bir özellik , bir boşluğun ayrılması gerektiğini uygulamalara bildirmek için bir elenete yapıştırılabilir.Geçerli dokümanlarda , bu özellik , diğerleri gibi kullanılmadan önce tanımlanmış olmalıdır.Tanımlandığı zaman mümkün olan değerleri default ve preserve olan bir enumeration tipi şeklinde tanımlanmış olmalıdır. Örneğin:
xml:space (default|preserve) 'preserve'>
gibi Default değeri , bu element için uygulamanın varsayılan boşluk işleme modlarının uygun olacağını belirtmektedir.Preserve değeri ise uygulamaların boşlukları korumaları gerektiğini kendilerine bildirmektedir.Bu tanımlar yapıldıkları yerdeki tüm elementler için herhangi başka bir xml:space tanımı yapılmadığı sürece geçerlidir.Herhangi bir dokümanın kök elemanının uygulama boşluk ele alımı için bir değer belirtmediği sürece herhangi bir belirleme yapmadığı düşünülmektedir.
Satır Sonu Ele Alımı XML parse edilmiş varlıkları genellikle satırlara ayrılmış bilgisayar dosyaları şeklinde saklanmaktadırlar.Bu satırlar tipik olarak #xD ve #xA kombinasyonları şeklinde belirlenmişlerdir.Uygulamaların işlevlerini basite indirgemek için , herhangi bir parse edilmiş varlık veya literal varlık değeri #xD#xA sırası veya sadece #xD literali içeriyorsa , XML işleyici uygulamaya sadece #xA karakterşnş geçirmelidir.Bu literallerin normalize edilme işlemidir. Dil Tanımlama Doküman işlemede , genellikle içeriğin yazıldığı doğal veya formal dilin tanımlanması oldukça önemlidir.xml:lang adı verilen bir özellik , içerik dili ve özellik değerlerinin tanımlanmasında dokümanlar içerisinde kullanılabilir.Geçerli dokümanlarda , özellik kullanılmadan önce tanımlanmış olmalıdır.Özellik için geçerli olan değerler IETF RFC 1766 standardı ile belirlenmiş dil tanımlayıcılarıdır.
Dil Tanımı Grameri [33] [34] [35] [36] [37] [38]
LanguageID ::= Langcode ('-' Subcode)* Langcode ::= ISO639Code | IanaCode | UserCode ISO639Code ::= ([a-z] | [A-Z]) ([a-z] | [A-Z]) IanaCode ::= ('i' | 'I') '-' ([a-z] | [A-Z])+ UserCode ::= ('x' | 'X') '-' ([a-z] | [A-Z])+ Subcode ::= ([a-z] | [A-Z])+
Langcode izleyenlerden herhangi biri olabilir: -ISO 639 tarafından tanımlanmış iki harfli dil kodu -IANA(Internet Assigned Numbers Authority) tarafından belirlenmiş dil tanımlayıcısı(i ıle başlayan) kullanıcı tarafından atanmış dil tanımlayıcısı(x ile başlayan). Bu tanımların IANA ile çakışmaması için x kullanılmaktadır.Herhangi bir sayıda altkod segmenti olabilir ; eğer ilk altkod segmenti bulunuyor ve altkod iki harften oluşuyorsa o zaman kod ISO 3166 dan bir ülke olmalıdır.Eğer ilk altkod iki den daha fazla kod bulunduruyorsa o zaman IANA ile kaydedilmiş bir dil kodu olmalıdır.Genellikle dil kodu küçük harflerle verilir ve ülke kodu ise büyük harflerle verilir.XML dokümanlarındaki diğer isimlerin tersine bu değerler büyük ve küçük harf ayrımı yapmazlar. Örneğin:
The quick brown fox jumps over the lazy dog.
What colour is it?
What color is it?
Şarap üzümden yapılır.
<sp who="Faust" desc='leise' xml:lang="de">
Habe nun, ach! Philosophie, Juristerei, und Medizin und leider auch Theologie durchaus studiert mit heißem Bemüh'n. xml:lang ile yapılan tanımlamalar , başka bir xml:lang tanımlaması yapılmadığı sürece , element içeriği ve özelliklerin tümü için geçerlidir.xml:lang için basit bir tanımxml:lang NMTOKEN #IMPLIED şeklini alabilir fakat ayrıca spesifik değerlerde verilebilir. Örnek:
XML Grameri
- Bölüm 4
Mantıksal Yapılar Her XML dokümanı bir veya daha fazla element içermektedir ve bu elementlerin sınırları başlangıç,bitiş veya boş eleman tag i ile belirlenmektedir.Her elemanın bir tipi , kendisini belirleyen bir ismi(jenerik tanımlayıcısı) , ve bir özellik spesifikasyon kümesi bulunmaktadır.Her özellik spesifikasyonunun ismi ve değeri bulunmaktadır.
Element grameri [39] element ::= EmptyElemTag | STag content ETag [ WFC: Element Type Match ] Element Valid ]
[ VC:
Bu spesifikasyon eleman tiplerinin ve özelliklerinin anlam , kullanım ve isimlerini kısıtlamaz(x,m,l dışında (Bu değerler ileriki versiyonlardaki standardizasyon için kullanılmak istenmektedir)) İyi-Oluşturulma Kısıtlaması: Bir elemanın bitiş tag indeki isim başlangıçtaki ile uyuşmalıdır. Geçerlilik Kısıtlaması: Element tipi uyuşması Eğer • • • • •
İsim in element tipi ile uyuştuğu ve elementdecl ile uyuşan bir tanım ile uyuşan bir tanım varsa ve Tanım EMPTY ile uyuşmakta ve element içeriği yoksa Tanım içerik modelinde belirlenen sıradan ifadelerdeki children ve children element sırası ile uyuşmakta ise Tanım Mixed ile uyuşmakta ve içerik , içerik modelindeki karakter verisi ve child elementleri içermekte ise Tanım ANY ile uyuşmakta ve childe elementlerin tanımlamalarının tipleri ile uyuşmakta ise
eleman geçerlidir. Başlangıç tag leri , Bitiş Tagleri , Boş Eleman Tagleri Her boş olmayan XML elemanı bir başlangıç etiketi ile işaretlenmektedir.
Başlangıç Etiketi Grameri [40] STag ::= '<' Name (S Attribute)* S? '>' [ WFC: Unique Att Spec ] [41] Attribute ::= Name Eq AttValue [ VC: Attribute Value Type ] [ WFC: No External Entity References ] [ WFC: No < in Attribute Values ]
Başlangıç ve Bitiş etiketlerindeki isimler elemanın tipini belirlemektedirler.İsim - Özellik ikilileri elemanın özellik spesifikasyonları olarak adlandırılır.(Özellik İsmi - Özellik değeri) İyi oluşturulma kısıtlaması 1: Özelliğe Özgü Spesifikasyon Aynı başlangıç etiketinde ve boş eleman etiketinde özellik ismi birden fazla kez belirlenemez Geçerlilik kısıtlaması: Özellik tanımlanmış olmalıdır;değer tanımlanan tipe sahip olmalıdır. İyi oluşturulma kısıtlaması 2: Dış varlık referansları bulunmamalıdır Özellik değerleri direkt veya indirekt olarak dış varlıklara varlık referanslarında bulunamazlar İyi oluşturulma kısıtlaması 3: Özellik değerlerinde < bulunmaması Özellik değerinde belirlenen yerdeğiştirme metni < karakteri barındıramaz Bir başlangıç terimi örneği:
Bir başlangıç etiketi ile başlayan her eleman elemanın ismini barındıran bir bitiş etiketi ile işaretlenmek zorundadır. Bitiş etiketi grameri [42] ETag ::= '' Name S? '>'
Örnek: Başlangıç ile Bitiş etiketleri arasındaki metine elemanın içeriği adı verilir.
Eleman içeriği grameri [43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
Eğer bir eleman boş ise , başlangıç etiketini izleyen bir bitiş etiketi olmalıdır.Boş eleman etiketi ise özel bir form almaktadır. Boş eleman etiketi grameri [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>' [ WFC: Unique Att Spec ]
Boş eleman etiketleri , EMPTY olarak tanımlanıp tanımlanmadıklarından bağımsız olarak , içeriği olmayan elemanlar için kullanılmaktadırlar.Uygulamalar arasında uyum sağlamak için ise sadece EMPTY olarak tanımlanan elemanlar için bu etiketlerin kullanılması önerilmektedir. Örnek:
XML Grameri
- Bölüm 5 -
Eleman tipi tanımları Bir XML dokümanının eleman yapısı , geçerleme sebeplerinden dolayı eleman tipi ve özellik listesi tanımları tarafından kısıtlamalara uğrayabilir.Eleman tipi tanımı bir elemanın içeriğini kısıtlar. Eleman tipi tanımları genellikle hangi eleman tiplerinin , elmanın children tipleri olarak ortaya çıkacağını belirler.Kullanıcı opsiyonu olarak bir XML işleyici tanımın vermediği bir eleman tipi için bir uyarı mesajı verebilir ancak bu bir hata değildir.
Eleman tipi tanımı grameri [45] elementdecl ::= '' [ VC: Unique Element Type Declaration ] [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
Burada Name tanımlanan eleman tipini belirtmektedir. Geçerliik kısıtlaması: Hiçbir eleman tipi bir kereden fazla tanımlanamaz Örnekler:
br EMPTY> p (#PCDATA|emph)* > %name.para; %content.para; > container ANY>
Eleman İçeriği Bir eleman tipinin kendi tipinde child elemanlar barındırması(karakter verisi değil) durumunda eleman içeriği bulunmaktadır.Bu durumda kısıtlama bir içerik modeli içermektedir.Bu child elemanların izin verilen tiplerini ve görünme sıralarını düzenleyem basit bir gramerdir.Gramer , içerik parçaları halinde (cp) oluşturulmakta ve bu isimler . içerik parçacıkları seçenek veya sıra listelerinden oluşmaktadır.
Eleman içerik modelleri grameri [47] [48] [49] [50]
children ::= (choice | seq) ('?' | '*' | '+')? cp ::= (Name | choice | seq) ('?' | '*' | '+')? choice ::= '(' S? cp ( S? '|' S? cp )* S? ')' [ VC: Proper Group/PE Nesting ] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')' [ VC: Proper Group/PE Nesting ]
Bu gramerde Name , child eleman olarak beliren elemanların tiplerini göstermektedir.Seçenek listesindeki herhangi bir içerik parçası gramerde seçenek listesinin belirdiği herhangi bir eleman içeriği şeklinde ortaya çıkabilir;bir sırada beliren içerik parçaları listede belirdikleri sırada eleamn içeriğinde varolmalıdırlar.Bir ismi takip eden opsiyonel karakterler , elemanın veya içerik parçalarının bir veya daha fazla bir şekilde belirmelerini yönetir.Böyle bir işaretin yokluğu eleman veya içerik parçasının sadece bir kere belireceğini göstermektedir.Bir elemanın içeriği , içerik modeli ile , eğer sadece içerik modelinden bir yol çıkarmak mümkün ise uygunluk gösterir.Ve bu şekilde sıra , seçim tekrarlama operatörlerine uyum ve içerikteki her
elemanın , içerik modelindeki eleman tipine uygunluğu sağlanır.Uyum için,eğer dokümandaki bir eleman içerik modelindeki birden fazla eleman tipi ile uyum gösterirse,bu hata demektir. Geçerlilik kısıtlaması:Uygun Grup / Parametre Varlığı(PE) Yuvalaması Parametre - varlık yerdeğiştirme metni parantezli gruplarda uygun bir şekilde yuvalanmalıdır.Eğer choice,seq,veya Mized yapısında parantez açımı ve kapatımı bir parametre varlığı yerdeğiştirme metninde yer alıyorsa , ikisi de aynı yerdeğiştirme metninde yer almalıdır.Uygulamalar arası adaptasyon için eğer bir parametre-varlık referansı bir choice,seq,veya Mized yapısında ortaya çıkıyor ise yer değiştirme metni boş olmamalı ve ilk ve son karakterler bağlayıcı karakterlerden(,|) olmamalıdır. Örnekler Karışık içerik Bir eleman tipi , bu tipin elemanları karakter verisi ve isteğe bağlı olarak child elemanlar ile karıştığında karışık(mixed) içeriğe sahiptir denir.Bur durumda child elemanların tipler kısıtlanabilir ancak sıraları ve sayıları kısıtlanamaz Karışık içerik grameri [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')' [ VC: Proper Group/PE Nesting ] [ VC: No Duplicate Types ]
Name children olarak belirebilecek elemanların tiplerini vermektedir. Geçerlilik kısıtlaması: Tek bir karışık içerik tanımında aynı izim birden fazla olarak beliremez Örnekler:
XML Grameri
- Bölüm 6 -
Özellik – Liste Tanımları Özellikler , isim – değer ikililerini elemanlar ile ilişkilendirmek için kullanılmaktadırlar.Özellik spesifikasyonları sadece başlangıç etiketlerinde ve boş eleman etiketlerinde bulunabilirler. Özellik – liste tanımları • Belli bir eleman tipi için olan özellik kümesini tanımlamak için • Bu özelliklere tip kısıtlamaları sağlamak için • Özelliklere varsayılan değerler atamak için Kullanılmaktadırlar. Kısaca özellik – liste tanımları bir eleman tipinin her özelliği için veri tipini , ismi ve varsa varsayılan değerleri tanımlar. Özellik – Liste tanımı grameri [52] AttlistDecl ::= '' [53] AttDef ::= S Name S AttType S DefaultDecl
AttlistDecl kuralı içerisinde görülen isim elamn tipidir.Kullanıcı seçeneğinde , tanımlanmamış bir eleman tipinde özellikler tanımlanmış ise , bir XML işleyici uyarı mesajı verebilir ancak bu bir hata değildir.AttDef kuralındaki isim ise özelliğin ismidir. Belirlenen bir eleman tipi için birden fazla özellik tanımı varsa tümünün içeriği birleştirilir.Bir elaman tipinin bir özelliği için , eğer birden fazla tanım bulunuyor ise ilk tanım bağlayıcı tanımdır ; diğerleri gözardı edilir. Uygulamalar arası uyumlu çalışma için DTD yazıcıları belirlenen bir eleman tiği için en çok bir özellik – liste tanımlamasına izin verebilirler ve bu tanım içerisinde en çok bir özellik tanımı içerilmesini belirleyebilirler. Özellik tipleri XML Özellik Tipleri 3 çeşittirler: String tipi , Tokenized (Ayrıştırılmış ) tipler ve enumerated tipler. Strin g tipi değer olarak literal değerler alabilirken , tokenized tipler lexical ve anlam kısıtlamalarına sahip olabilmektedirler.
Özellik Tipleri Grameri [54] AttType ::= StringType | TokenizedType | EnumeratedType [55] StringType ::= 'CDATA' [56] TokenizedType ::= 'ID' [ VC: ID ] [ VC: One ID per Element Type ] [ VC: ID Attribute Default ] | 'IDREF' [ VC: IDREF ] | 'IDREFS' [ VC: IDREF ] | 'ENTITY' [ VC: Entity Name ] | 'ENTITIES' [ VC: Entity Name ] | 'NMTOKEN' [ VC: Name Token ] | 'NMTOKENS' [ VC: Name Token ]
Geçerlilik kısıtlaması:
ID
ID (Kimlik) tipinin değerleri isim üretimine uymak zorundadır.Bir isim , bu tip için XML dokümanının içerisinde birden fazla bulunmamalıdır.ID değerleri kendisini taşıyan elemanlara özgü değerler olmalıdırlar. Geçerlilik kısıtlaması:
Her eleman tipi için bir ID
Birden fazla ID özelliğine sahip herhangi bir eleman tipi olamaz Geçerlilik kısıtlaması:
Varsayılan ID Özelliği
Bir ID özelliğinin #IMPLIED veya #REQUIRED ile belirlenen varsayılan bir değeri olmalıdır. Geçerlilik kısıtlaması:
IDREF
IDREF değerleri isim üreitimine uymak zorundadırlar ve IDREF tipinin değerleri İsimler ile uyuşmalıdır ; her İsim XML dokümanında bulunan bir elemanın ID özelliğine uymak zorundadır. Geçerlilik kısıtlaması:
Varlık İsmi
ENTITY değerleri isim üretimine uymak zorundadırlar ve ENTITIES tipleri İSimler ile uyuşmak zorundadırlar ; her ismin DTD içerisinde tanımlanan bir unparsed varlık ile uyuşması gerekmektedir. Geçerlilik kısıtlaması:
Name Token (İsim parçası)
NMTOKEN değerleri NmToken üretimine uymak zorundadır ; NMTOKENS değerleri de Nmtokens ile uyuşmak zorundadır. Enumerated özellikleri tanımda belirlenen değer listelerinin içerisinden bir değere sahip olabilirler.
Enumerated Attribute Types [57] EnumeratedType ::= NotationType | Enumeration
[58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')' [ VC: Notation Attributes ] [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')' [ VC: Enumeration ]
NOTATION özelliği bir DTD içerisinde ilişkili system ve public belrteçler ile tanımlanmış ve özelliğin bağlandığı eleman ile işlenecek belirtim göstermektedir. Geçerlilik kısıtlaması:
NOTATION özellikleri
Bu tipteki değerler tanımda belirlenen bir NOTATION ismi ile uyuşmak zorundadırlar ve tanımdaki tüm belirtim isimleri tanımlanmış olmalıdır. Geçerlilik kısıtlaması:
Enumeration
Bu tipteki değerler Nmtoken içerisinde belirtilen bir parça ile uyuşmalıdır. Özellik Varsayılan Değerleri Bir özellik değeri özelliğin gerekli olup olmadığı hakkında bilgi sağlamakta , ve eğer gerekli değilse , dokümanda bu özelliğin olmaması durumunda XML işleyicinin nasıl davranması gerektiğini belirlemektedir.
Özellik Varsayılan Değerleri Grameri [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue) [ VC: Required Attribute ] [ VC: Attribute Default Legal ] [ WFC: No < in Attribute Values ] [ VC: Fixed Attribute Default ]
Özellik tanımında , #REQUIRED özelliğin değerinin daima belirlenmesi gerektiğini belirlerken #IMPLIED ise herhangi bir varsayılan değerin bulunmadığını göstermektedir.Eğer tanım #REQUIRED ve #IMPLIED değil ise o zaman AttValue değeri tanımlanan varsayılan değeri içermektedir ; #FIXED kelimesi özelliğin daima belirtilen varsayılan değere sahip olacağını gösterir.XML işleyicisi kısaltılmış bir özellik ile karşılaştığında , eğer varsayılan değer tanımlanmış ise , tanımlanmış varsayılan değer ile özellik bulunuyormuş gibi davranmalıdır. Geçerlilik kısıtlaması:
Gerekli Özellik
Eğer varsayılan tanım #REQUIRED ise o zaman özellik özellik - liste tanımında bulunan aynı tipteki tüm elemanlar için belrilenmiş olmalıdır. Geçerlilik kısıtlaması:
Özellik Değerinin Kurallara uygunluğu
Tanımlanan varsayılan değer tanımlanan özellik tipi için varolan tüm lexical kısıtlamalar ile uyumluluk göstermelidir. Geçerlilik kısıtlaması:
Sabit Özellik Varsayılan Değeri
Eğer bir özelliğin #FIXED ile tanımlanmış bir varsayılan değeri bulunuyorsa bu özelliğin belirtimleri varsayılan değer ile uyum göstermelidir. Örnekler: Özellik – Değer Normalizasyonu Bir özelliğin değeri uygulamaya geçirilmeden yada geöerleme için control edilmeden önce , XML işleyicinin bu değeri aşağıdaki şekilde normalize etmesi gerekmektedir.
• • •
Bir karakter referansı özellik değerine referans edilen karakterin sondan eklenmesi ile işlenir Bir varlık referansı varlık yer değiştirme metninin rekürsif olarak işlenmesi ile işlenir Bir boşluk karakteri (#x20 , #xD , #xA , #x9) , normalize edilmiş değerin sonuna #x20 eklenmesi ile işlenir ancak dış parse edilmiş bir varlık veya içsel parse edilmiş bir literal varlık değerinin ‘#xD#xA’ sırası için tek bir #x20 eklenmektedir.
Eğer tanımlanan değer CDATA değilse , o zmaan XML işleyicinin normalize edilmiş özellik değerini başta ve sondaki boşluk karakterlerini elimine etmesi (trim) gerekmektedir. Tanım okunmayan tüm özellikler ise CDATA şeklinde tanımlanmıl oldukları Kabul edilerek geçerleme yapmayan bir parser ile ele alınmalıdır. Şartlı bölümler Şartlı bölümler , kendilerini yöneten DTD tanımındaki anahtar kelimenin içinde bulunan ya da dışında referans edilen DTD dış altkümesi kısımlarıdır.
Şartlı bölüm grameri [61] [62] [63] [64] [65]
conditionalSect ::= includeSect | ignoreSect includeSect ::= '' ignoreSect ::= '' ignoreSectContents ::= Ignore ('' Ignore)* Ignore ::= Char* - (Char* ('') Char*)
İç ve dış DTD altkümelerinde olduğu gibi , bir şartlı kısım bir veya daha fazla tam tanımlar , yorumlar , işleme komutları , veya yuvalanmış şartlı kısımlar içerebilmektedir.Eğer şartlı kısım için anahtar kelime INCLUDE ise o zaman şartlı kısmın içeriği DTD nin bir parçasıdır.Eğer anahtar kelime IGNORE ise o zaman şartlı kısmın içeriği mantıksal olarak DTD nin içeriği değildir.Güvenilebilir bir parse işlemi için şartlı bölümler IGNORE olarak belirlenmiş bile olsa yuvalanmış şartlı bölümlerin tetkik edilebilmesi için bu bölümler okunmalı ve en dıştaki şartlı bölüm sonu düzgün bir biçimde belirlenmelidir.Eğer INCLUDE içeren bir şartlı bölüm kendinden daha üst seviyede bulunan IGNORE anahtar kelimeli bir şartlı bölüm içerisinde bulunuyorsa , hem içteli hem de dıştaki şartlı bölümler IGNORE anahtar kelimeli olarak ele alınmalıdır. Eğer şartlı bölüm için anahtar kelime bir parameter-varlık referansı ise , parameter varlığı iişleyici şartlı bölümü ihtiva edip etmeyeceğine karar vermeden önce kendi içeriği ile yer değiştirmiş olmalıdır. Örnek: ]]> ]]>
XML Grameri
- Bölüm 7 -
Fiziksel Yapılar Bir XML dokümanı bir veya daha fazla saklama birimlerinden oluşabilmektedir. Bu birimler varlık olarak adlandırılmaktadırlar ve hepsinin içerikleri ve isimleri bulunmaktadır.Her XML dokümanının doküman varlığı adı verilen bir varlığı bulunmaktadır ve bu varlık XML işleyicisi için bir başlangıç noktası oluşturmakta ve tüm dokümanı içermektedir.Varlıklar parse edilmiş veya edilmemiş olabilirler.Parse edilmiş bir varlığın içeriği onun yer değiştirme metni olarak adlandırılır;bu metin doküman ile entegre olan bir kısım olarak kabul edilir. Parse edilmemiş bir varlık içeriği metin olabılen veya olmayabilen bir kaynaktır ancak içerik metin ise bu bir XML olamaz.Her parse edilmemiş varlığın ilişkili bir gösterimi bulunmaktadır.XML işleyicinin varlık iöin belirteçler yapma gereksinimi ve uygulamaya sunulan gösterimin ötesinde XML parse edilmemiş varlıkların içeriklerine kısıtlama koymamaktadır. Parse edilmiş varlıklar varlık referansları kullanılarak bir isim ile çağrılırlar;parse edilmemiş olanlar ise ENTITY ve ya ENTITIES özellikleri ile belirtilen isimler ile çağrılmaktadır. Genel varlıklar doküman içeriği ile kullanılmak içindir.Bu spesifikasyonda genel varlıklar bazen varlık terimi ile kullanılmaktadır.Parametre varlıkları DTD ile kullanılmak özere kullanılan parse edilmiş varlıklardır.Bu iki çeşit varlıklar farklı biçimlerdeki referanslar kullanmaktadır ve farklı kontekstlerde tanınmaktadır.Ayrıca farklı isim uzaylarına sahiptirler;bir parametre varlığı ve bir genel varlık aynı isimde olsalar da iki farklı varlıktırlar.
Karakter ve Varlık Referansları Bir karakter referansı ISO/IEC 10646 karakter kümesinde bir karakteri temsil etmektedir , ve bunlara direkt olarak girdi aygıtından girilmesi mümkün olmayan karakterler de dahildir. Karakter Referans Grameri [66] CharRef ::= '' [0-9]+ ';'
| '' [0-9a-fA-F]+ ';' [ WFC: Legal Character ]
İyi oluşturulma kısıtlaması: Yasak olmayan karakterler Char gramerinde verilen gramer referans verilen karakterleri içermelidir.Eğer karakter referansı ile başlarsa ; işaretine kadar olan kısımdaki sayı ve harfler karakterin kodu için onaltılık düzende (hex) bir sunum sağlarlar.Eğer sadece ile başlarsa o zaman bu kısım ondalık düzende bir gösterim sağlamaktadır. Bir varlık referansı , isimlendirilen bir varlığın içeriğini belirtmektedir.Parse edilmiş genelvarlıklara referanslar & ve ; limitleyici işaretle olarak kullanmaktadırlar.Parametre – Varlık referansları ise aynı işlevi % ve ; işaretleri ile sağlamaktadırlar. Varlık referans grameri [67] Reference ::= EntityRef | CharRef [68] EntityRef ::= '&' Name ';' [ WFC: Entity Declared ] [ VC: Entity Declared ] [ WFC: Parsed Entity ] [ WFC: No Recursion ] [69] PEReference ::= '%' Name ';' [ VC: Entity Declared ] [ WFC: No Recursion ] [ WFC: In DTD ]
İyi oluşturulma kısıtlaması: Tanımlanan varlıklar DTD olmayan herhangib bir dokümanda , sadece bir iç DTD altkümesi bulunan ve parametre varlık referansları bulunmayan bir dokümanda veya standalone değeri yes olan bir dokümanda , varlık referansında verilen “Name” değeri bir varlık deklarasyonu ile uyuşmalıdır fakat iyi oluşturulmuş dokümanlar amp,lt,gt,apos,quot varlıklarını tanımlamış olmamalıdır.Bir parameter varlığı tanımı kendisine yapılan herhangi bir referanstan önce yapılmış olmalıdır.Benzer olarak , genel bir varlığın tanımı kendisine yapılan bir referanstan önce olmalıdır.Eğer varlıklar dış altkümelerde veya dış parameter varlıklarında tanımlanmış ise geöerleme yapmayan bir işleyici bu tanımları okumak ve işlemek zorunda değildir.Böyle dokümanlar iöin eğer sadece standalone değeri yes ise varlığın tanımlanmış olması bir iyi oluşturulma kriteridir. Geçerlilik Kısıtlaması : Tanımlanan varlıklar Dış altküme veya dış parameter varlıkları barındıran ve standalone = no değeri taşıyan bir dokümanda , varlık referansında verilen Name değeri varlık tanımı ile uyuşmalıdır.Programlar arası uyum için geçerli dokümanlar amp,lt,gt,apos,quot varlıklarının tanımını yapmalıdır.Bir parametre varlık tanımı ona yapılan referanstan önce olmalıdır.Benzer olarak , genel bir varlığın tanımı referansında önce yapılmış olmalıdır. İyi oluşturulma kısıtlaması: Parse edilmiş varlıklar Bir varlık referansı parse edilmemiş bir varlığın ismini barındırmamalıdır.Parse edilmemiş varlıklar sadece ENTITY veya ENTITIES tipinde tanımlanmış özellik değerlerinde kullanılabilirler. İyi oluşturulma kısıtlaması: Recursion olmamalıdır Bir parse edilmiş varlık kendisine direk veya dolaylı oldan referansta bulunamaz İyi oluşturulma kısıtlaması: DTD içerisinde bulunma Parametre – Varlık referansları sadece DTD içerisinde bulunabilirler. Örnekler: Karakter ve Varlık Referansı Lütfen seçenekleri kaydetmek için
less-than (<) seçiniz Bu doküman &doctarih; tarihinde ve &security-level; güvenlik seviyesinde hazırlanmıştır.
Parametre – Varlık Referansı %ISOLat2;
XML Grameri
- Bölüm 8 -
Varlık Tanımları Varlık tanımlarının grameri aşağıdaki şekildedir.
Varlık deklarasyon grameri [70] [71] [72] [73] [74]
EntityDecl ::= GEDecl | PEDecl GEDecl ::= '' PEDecl ::= '' EntityDef ::= EntityValue | (ExternalID NDataDecl?) PEDef ::= EntityValue | ExternalID
Name değeri bir varlık referansındaki varlığı veya bir parse edilmemiş varlık durumunda , ENTITY veya ENTITIES özelliğinin değerinin belirtmektedir.Eğer aynı varlık bir kerede fazla tanımlanmış ise ilk tanım bağlayıcı tanımdır ; kullanıcı opsiyonunda bir XML işleyici , eğer varlıklar birden fazla tanımlandı ise uyarı mesajı verebilir. İç varlıklar Eğer bir varlık tanımı EntityValue ise tanımlanan varlık bir iç varlık olarak adlandırılır.Ayrı bir fiziksel saklama nesnesi bulunmamaktadır ve varlığın içeriği tanımda verilmektedir.Bir iç varlık , parse esilmiş bir varlıktır. Örnek: Dış varlıklar Eğer varlık içsel değilse o zaman bir dış varlıktır ve tanımı izleyen şekildedir. Dış varlık deklarasyon grameri [75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral [76] NDataDecl ::= S 'NDATA' S Name [ VC: Notation Declared ]
Eğer NDataDecl mevcut ise bu genel bir parse edilmemiş varlıktır fakat tersi durumda bir parse edilmiş varlık belirtimidir. Geçerlilik Kısıtlaması : Belirtim Tanımlaması Name içerisinde belirtilen değer belirtim için tanımlanan isim ile uyuşmalıdır.
SystemLiteral , varlığın sistem belirteci olarak adlandırılır.Bu varlığın elde edilmesi için kullanılan bir URI dır.# işareti ve fragman belirteci URI ile kullanılması durumunda URI parçası değildir ; bir XML işleyici eğer fragman belirteci sistem belirteci olarak kullanılırsa , bir hata mesajı verebilir.Böylelikle bir URI doküman varlığı, dış DTD altkümesini içeren varlık veya başka bir dış parametre varlığı ile ilişkili olabilir. Bir XML işleyici ASCII olmayan bir karakteri URI içerisinde karakteri UTF – 8 düzeninde belirterek bir veya daha fazla byte şeklinde URI gösterim mekanizmasını kullanarak gösterebilir.(%HH à HH hexadecimal gösterim) Sistem belirtecinin yanısıra bir dış belirteç bir public belirteç içerebilmektedir.Varlığın içeriğini elde etmeye çalışan bir XML işleyici alternatif bir URI oluşturmak için public belirteci kullanabilir.Bir karşılaştırma denenmeden önce public identifier normalize edilmelidir. Dış Varlık Örnekleri: Parse Edilmiş Varlıklar Metin tanımları Dış parse edilmiş varlıklar bir metin tanımı ile başlayabilirler. Metin Tanımı Grameri [77] TextDecl ::= ''
Bir metin tanımı literal olarak verilmelidir , bir parse edilmiş varlığa referans edilerek yapılmamalıdır.Dış parse edilmiş varlığın ilk kısmından başka yerde bir metin tanımı bulunamaz. İyi oluşturulmuş parse edilmiş varlıklar Doküman varlığı eğer doküman etiketi ile uyum sağlıyorsa iyi oluşturulmuş demektir.Benzer şekilde bir dış genel parse edilmiş varlık extParsedEnt etiketi ile uyum sağlıyorsa iyi oluşturulmuş demektir.Dış parametre verlığı da extPE etiketi ile uyum sağlıyorsa iyi oluşturulmuş demektir.
İyi oluşturulmuş dış parse edilmiş varlık grameri [78] extParsedEnt ::= TextDecl? content [79] extPE ::= TextDecl? extSubsetDecl
Bir iç genel parse edilmiş varlık eğer content etiketi ile uyum sağlayan bir yer değiştirme metnine sahipse , iyi oluşturulmuş demektir.Tüm iç parametre varlıkları tanım usulü ile iyi oluşturulmuş demektir. İyi oluşmuş varlık sırası XML dokümanının içerisindeki mantıksal ve fiziksel yapıların uygun yerleştirilmesi demektir.Herhangi bir varlığın içerisinde başlayan başlangıç etiketleri,boş eleman etiketleri,eleman,yorum,işleme komutları,karakter referansları ve varlık referansları başka birinin içerisinde sonlanamamaktadır. Varlıklar içerisinde karakter kodlama Bir XML dokümanındaki her dış parse edilmiş varlık karakterleri için farklı bir kodlama sistemi kullanabilir.Tüm XML işleyicileri UTF-8 veya UTF-16 kodlamasını okuyabilmelidir.UTF-16 ile kodlanmış varlıklar ISO/IEC 10646 standardı ile tanımlanmış Byte Sıra İşareti kullanılarak kodlanmış olmalıdır.Bu kodlama imzasıdır , XML dokümanının bir karakter verisi yada işaretlemesi değildir.XML işleyiciler bu karakteri UTF-8 ve UTF-16 kodlamalı dokümanları birbirinden ayırmak için kullanılmaktadır. Bir XML işleyicisi UTF-8 ve UTF-“6 kodlamalarını okumak için kullanılırken dünyada kullanılan kodalma standardları , XML işleyicileri için spesifik olarak dizayn edilebilmektedirler.UTF-8 ve UTF-16 dışında bir kodlama standardı ile hazırlanmış parse edilmiş varlıklar kodlama tanımını içeren bir metin tanımı ile başlamalıdırlar.
Kodlama tanım grameri [80] EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" ) [81] EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')* /* Kodlama ismi sadece Latin karakterler içerebilir */
Doküman varlığında kodalma deklarasyonu XML tanımının bir parçasıdır.Bir kodlama tanımında , UTF-8 , UTF-16,”ISO-10646-UCS-2” ve “ISO-10646-UCS-4” Unicode / ISO / IEC 10646 standardlarının çeşitli kodlamaları için , “ISO-8859-1”,”ISO-8859-2” … “ISO-8859-9” ISO 8859 kısımları için ve “ISO-2022JP”,”Shift_JIS” ve “EUC-JP” ise JIS X-0208-1997 standardının çeşitli formları kullanılmalıdır.XML işleyicileri diğer kodlamaları tanıyabilirler. Bir dış transfer protokolünün sağladığı bilginin yokluğunda (HTML veya MIME) tanımda belirtilen kodlama tanımının dışında bir kodlama kullanmak XML işleyici için hata teşkil etmektedir.Ayrıca XML işleyicinin işleyemeyeceği bit kodlama tanımına sahip varlıklar fatal error oluşturacaktır.
Kodlama Örneği:
XML Grameri
- Bölüm 9 -
Varlık ve Referansların XML İşleyici Tarafından Ele Alınması Aşağıdaki tablo bir XML işleyicide karşılaşılması muhtemel tüm karakter referansları , varlık referansları ve parse edilmemiş varlık çağrılarını içermektedir. İçerik Referansı elemanın başlangıç etiketinden başlayan ve bitiş etiketine kadar olan ve content nonterminali için geçerli olan referanstır. Özellik Değer Referansı ya başlangıç etiketindeki özelliğin değeri yada bir özellik değerindeki varsayılan değerdir ve AttValue nontermiani için geçerli olan referanstır. Özellik Değeri Olarak Ortaya Çıkma bir Name değeri olarak referasn değildir ve ENTITY olarak tanımlanan bir özelliğin değeri yada ENTITIES olarak tanımlanan özelliğin değerinde yer alan boşluk ile ayrılmış bileşenlerdir. Varlık Değeri Referansı iç varlığın literal varlık değerindeki veya parametresindeki varlık tanımında yer alan ve EntıtyValue nonterminali için geçerli olan referanstır. DTD Referansı DTD nin iç veya dış altkümelerinde yer alan referanstır fakat bu EntityValue ve AttValue dışında yer almaktadır. Varlık Tipi Parametre
İç Genel
Dış Parse Edilmiş Genel Geçerlemede dahil Yasak
Parse Edilmemiş Yasak
Karakter Dahil
Yasak
Dahil
Yasak
Uyarı
Tanınmaz
İçerik Referansı
Tanınmaz
Dahil
Özellik Değer Referansı Özellik Değeri Olarak Ortaya Çıkma Varlık Değeri Referansı DTD Referansı
Tanınmaz Tanınmaz
Literalde dahil Yasak
Literalde dahil
Gözardı edilir
Gözardı edilir
Yasak
Dahil
PV olarak dahil
Yasak
Yasak
Yasak
Yasak
Tanınmaz DTD dışında , % karakterinin özel bir anlamı bulunmamaktadır,böylece DTD içerisindeki parametre varlık referansları içerik içerisinde işaretleme konteksti olarak ele alınmamaktadır.Benzer olarak , parse edilmemiş varlıların isimleri doğru olarak tanımlandıkları özelliklerin dışında tanınmamaktadırlar.
Dahil Bir varlık yer değiştirme metni elde edilip işlendiği takdirde “dahil” olarak adlandırılmaktadır ve referansın yerinde dokümanın bir parçası şekinde bu metin kullanılmaktadır.Yer değiştirme metni hem karakter verisi hem de işaretleme konteksti içerebilmekte ve bu normal olarak tanımlanmaktadır.Bu durumda kaçış işaret limitleyicileri (amp,lt,gt,apos,quot varlıkları) ise istisnai olarak daima veri olarak işlenmektedirler.Örnek olarak “AT&T;” , “AT&T” olarak genişlemektedir.Bir karakter referansı eğer belirtilen karakter referansın yerine işleniyor ise dahil olarak adlandırılmaktadır. Geçerlemede Dahil Bir XML işleyici işlenmiş bir varlığa referans gördüğünde , dokümanı geçerlemek için yer değiştirme metnini işlemesi gerektmektedir.Eğer varlık bir sış varlık ise ve işleyici XML dokümanını geçerlemeye uğraşmıyor ise işleyici varlığın yer değiştirme metnini içerebilir ancak bunu yapmak zorunda değildir.Eğer geçerleme yapmayan bir parser yer değiştirme metnini içermiyorsa o zaman uygulamaya bunun tanındığını ancak varlığı okumadığını belirtmelidir. Bu kural SGML ve XML varlık mekanizmasının otomatik içerme tanımlamasına dayalıdır ve tanımlamada modülerlik desteği için dizayn edilmiştir fakat diğer bazı uygulamalar (spesifik doküman araması gibi) için uygun değildir.Örneğin tarayıcılar dış parse edilmiş bir varlık referansı ile karşılaştıklarında varlığın bulunması ile ilgili bir görsel uayrı içerebilir ve sadece ihtiyaç duyulduğunda onu göstermek için elde edebilmelidirler. Yasak İzleyen tanımlar yasak ve hata verecek tanımlardır: • İşlenmemiş bir varlığa referans • DTD içerisinde EntityValue ve AttValue içerisinde yer almayan bir karakter veya genel varlık referansının bulunması • Özellik değerinde bir dış varlığa referans Literalde Dahil Bizr özellik değerinde varlık referansı bulunduğunda veya bir parametre varlık referansı literal varlık değerinde bulunduğunda , referansın kendisi yerine yer değiştirme metni referansın bulunduğu yerde sanki dokümanın bir parçası gibi işlenmektedir.Bunun istisnası yer değiştirme metninde yer alan tek veya çift tırnaklı karakter daima normal veri karakteri olarak ele alınmakta ve literali sonlandırmamaktadır.Örneğin iyi oluşturulmuşken izleyen örnek ise iyi oluşturulmamıştır. <element attribute='a-&EndAttr;> Uyarı İşlenmeiş bir varlığın ismi ENTITY veya ENTITIES olark tanımlanmış bir özellik değerinde görüldüğünde geçerleme yapan bir parser uygulamanın system ve public belirteçlerine varlık ve ilişkili gösterimi için bir uyarı yollamak zorundadır. Gözardı edilir EntityValue içerisinde bir genel varlık referansı görüldüğünde bu gözeardı edilmektedir. PV olarak dahil Dış parse edilmiş varlıklar gibi parametre varlıkları sadece geçerleme yapıyorlarsa içerilmelidirler.Parametre–Varlık referansları DTD tarafından tanındığında ve içerildiğinde , yer değiştirme metni başa ve sona bir #x20 boşluk karakteri ile genişletilmektedir; bunun amacı parametre varlığının yer değiştirme metninin DTD içerisinde belli sayıda gramatik bileşenlerinin sayısı içerme kısıtlamasıdır.
XML Grameri
- Bölüm 10 -
İç varlık yer değiştirme metninin oluşturulması İç varlık ele alınmasında varlık değerinin iki formunun birbirşnden ayrılması yararlı olacaktır.Literal varlık değeri varlığın tanımında gerçekten bulunan tırnaklı string dir ve değeri EntityValue nontermianli ile ilişkilendirilmiştir.Yer değiştirme metni ise karakter referanslarının ve parametre-varlık referanslarının yerleştirilmesinden sonra varlığın içeriği anlamına gelmektedir.
Literal varlık değeri bir i. Varlık tanımında verildiği üzere karakter,parametre-varlık ve genel varlık referansları içerebilmektedir.Böylesi rweferasnlar literal varlık değerinde tamamen içerilmelidirler.İöerilen gerçek yer değiştirme metni referans verilen herhangi bir varlığın yer değiştirme metnin içermeli ve literak varlık değerinde refere edilen karakterlerin yerine referans edilen karakterleri içermelidir fakat genel varlık referansları genişletilmeden olduğu gibi bırakılmalıdırlar.Örneğin tanımlarında kitap için verilen yer değiştirme metni La Peste: Albert Camus, © 1947 Éditions Gallimard. &rights; şeklindedir. Önceden tanımlı varlıklar Varlık ve karakter refernasları sol parantez , ampersand ve diğer delimitleyiciler için kullanılabilmektedirler.Bir genel varlık kümesi (amp,lt,gt,apos,quot) bu sebep için tanımlanmışlardır.Numeik karakter referansları ayrıca kullanılmaktadır ve tanındıkları anda hemen genişletilmektedirler. Tüm XML işleyicileri bu varlıkları tanımlı olsalarda olmasalarda tanımak zorundadırlar.Uygulamalar arası uyum için geçerli XML dokümanları bu varlıkları kullanmadan önce tanımlamalıdır.Eğer bu varlıklar tanımlandılarsa , tanımlamaları iç varlık şeklinde olmalı ve yer değiştirme metinleri kaçış karakteri veya bu karaktere referans olacak bir karaktere olacak şekilde tek karakterlik olmalıdır. Örnek:
lt "<"> gt ">"> amp "&"> apos "'"> quot """>
Dikkat edilmelidir ki lt ve amp tanımlarındaki < ve & karakterleri varlık yer değiştirmesinin iyi oluşturulmuş olması için iki kere escape edilmiştir. Gösterim Deklarasyonları Gösterimler , parse edilmemiş varlıkların düzenlerini,notation özelliği taşıyan elemanların düzenlerini veya işleme komutu bulunan bir uygulamayı isimleri ile belirtmektedirler. Gösterim deklarasyonları gösterim için bir isim sunmaktadır;bu isim varlı ve özellik liste tanımlarında ve özellik spesifikasyonlarında ve gösterim için bir dış belirteçde kullanılmaktadır.Dış belirteç XML işleyici veya client uygulamasının belirtilen gösterimde veriyi işleyen bir yardımcı uygulamanın yerini bulmasını sağlamaktadır. Gösterim Deklarasyon Grameri [82] NotationDecl ::= '' [83] PublicID ::= 'PUBLIC' S PubidLiteral
XML işleyicileri tanımlanan ve özellik değerlerinde,tanımlarında veya varlık tanımlarında referans edilen gösterimleri için isim ve dış belitreçleri ile uygulamaları sunmalıdırlar.Ayrıca ek olarak sistem belirteçlerinin içerisine dış belirteçleri,dosya isimlerini veya uygulamanın gösterimdeki veri için çağıracağı işleyici için gerekli bilgiyi çözümleyebilirler. Doküman varlığı Bir doküman varlığı bir XML işleyici için varlık ağacının kökünü ve başlangıcı belirtmektedir.Bu spesifikasyon doküman varlığının bir XML dokümantasyonu içerisinde nasıl yerleşeceğini belirtmemektedir ; diğer varlıkların tersine , doküman varlığı isime sahip değildir ve işleyicinin girdi akışında tanımsız olarak yer alabilmektedir. UYUMLULUK Geçerleme yapan ve yapmayan işleyiciler
Uyumlu XML işleyiciler iki sınıfa ayrılmaktadırlar.Geçerleme yapan ve yapmayan işleyiciler Geçerleme yapan ve yapmayan işleyiciler ve benzerleri olarak spesifikasyonların doküman varlığı içeriği ve diğer parse edilmiş varlıkların içerisinde belirtilen iyi oluşturulma kısıtlamaları uyumsuzluklarını belirtmek zorundadırlar.Geçerleme yapan işleyiciler DTD içerisinde tanımlanan kısıtlama ihlallerini bildirmelidir ve bu spesifikasyonda verilen geçerlilik kısıtlama ihlallerini incelemelidir.Bunu gerçekleştirmek için geçerleme yapan XML işleyiciler tüm DTD yi ve referans verilen dış parse edilmiş varlıkları okuyup işlemelidir. Geçerleme yapmayan işleyiciler sadece doküman varlığını kontrol etmek zorundadırlar , ve buna tüm iç DTD altkümesi iyi oluşturulma için dahildir.Dokümanın geçerliliğinin kontrol etme zorunlulukları olmadığı halde okudukarı herhangi bir parametre varlığı içindeki iç DTD altkümesinde okudukları tüm tanımları işlemek zorundadırlar.Bu işleyiciler okunmamış bir parametre varlığından sonra karşılaşılan varlık deklarasyonları ve özellik-liste tanımlarını işlemek zorunda değillerdir çünkü varlık başka üste çıkan tanımlarda içerilmiş olabilmektedir. XML işleyicilerin kullanılması Geçerleme yapan bir XML işleyicinin davranışı kolaylıkla tahmin edilebilir bir yapıdadır ; her parça dokümanı okumalı ve tüm iyi oluşturulma ve geçerlilik kısıtlaması ihlallerini bildirmelidir.Geçerleme yapmayan bir işleyiciden ise daha azı beklenmektedir;bu tip işleyiciler doküman varlığı dışında başka bir doküman parçasını okumak zorunda değildirler.Bunun XML işleyici kullanıcıları için iki önemli etkisi bulunmaktadır. • •
Belli başlı iyi oluşturulma hataları , özellikle dış varlık okuma gereksinimi olanlar , geçerleme yapmayan bir işleyici tarafından saptanmayabilir. İşleyiciden uygulamaya geçen bilgi işleyicinin parametre ve dış varlıkları okumasına göre değişebilir.Örneğin geçerleme yapmayan bir işeyici özellik değerlerini normalize etmeyebilir,iç varlıkların yer değiştirme metinlerini içerebilir,veya varsayılan özellik değerlerini tedarik edebilir ki tüm bunlar dış veya parametre varlıklaırının okunmasına göre değişmektedir
Farklı XML işleyicilerinin birbirileri ile çalışmasında maksimum güvenilirliği sağlamak için geçerleme yapmayan işleyicileri kullanan uygulamalr bu işleyiciler tarafından yapılmayan davranışlara güvenmemelidir.İç varlıklarda tanımlanan varsayılan özellik değerleri veya iç varlıklar gibi özellikler kullanan uygulamalar , geçerleme yapan XML işleyiciler kullanmalıdırlar.
Java ile hızlı bir XML PARSER YAZIMI Minimal kod ile geçerli bir XML dosyasının parse edilmesi Herkes SAX ve DOM gibi spesifikasyonları kullanan hazır XML Parser ları kullanır.Peki kendi XML Parser’ınızı yazmaya ve bunu kullanmaya ne dersiniz.Heyecan verici değilmi? Bu bölümde J2ME platformu uygulaması gibi alan kısıtlaması uygulanan bir ortamda XML kullanımı için XML Parser incelenecektir.Bu işlev XML Parser fonksiyonelliğini ufak uygulamaların kabul edebileceği düzeyde kısıtlayacaktır. XML insan tarafından okunabilir,kendini açıklayan ve taşınabilir bir veri düzeni olduğundan hızlı bir şekilde kabul görmektedir.Fakat ne yazık ki şu an bulunan Java destekli XML parser’ların çoğu oldukça büyüktür.Mesela Sun Microsystems’in jaxp.jar ve parser.jar XML parser kütüphanelerinin her biri yaklaşık 1.4 MB büyüklüğündedir.Eğer kısıtlı hafızaya sahip bir cihazda(J2ME) veya bant genişliğinin kısıtlı olduğu bir ortamda çalışıyor iseniz,bu parser’ların kullanımı uygun bir çözüm olmayabilir. Bu kütüphanelerin büyüklükleri birden fazla fonksiyonellik içermelerinden kaynaklanmaktadır ve bunlardan birçoğuna belki de ihtiyacınız yoktur.Bunlar, XML DTD geçerliliği,şemalar ve daha fazlası olabilir.Fakat siz uygulamanızın halihazırda geçerli bir XML dosyası aldığını biliyor olabilirsiniz.Böyle bir durumda , geçerleme yapmayan ve standard XML varlıklarının çevrimini yapan ve XML elemanlarını işleyen bir XML Parser’a ihtiyacınız olacaktır. Neden sadece SAX kullanmıyoruz? Uygulamanızda limitli fonksiyonelliğe sahip olan SAX API kullanabilirsiniz ve gereksiz olan işlevlerde NotImplemented excpetion’ı atabilirsiniz.Bu şekilde şüphesiz olarak 1.4 MB lık parser kütüphanlereinden daha ufak bir uygulama geliştirirsiniz fakat bunun yerine kodu daha fazla küçülterek kendi sınıflarınızı oluşturabilirsiniz.Burada oluşturulan paket SAX arayüz tanımlarını barındıran jar dosyasından daha az yer kaplayacaktır. XML Fonksiyonelliğinin Kısıtlanması
Birçok kişi XML’lerin basit ve kendi kendini açıklayan metin düzeninde bulunmasını ister.Basitçe elemanların,özelliklerin ve değerlerinin alınmasını ve elemanın metin içeriğinin okunmasını isterler.Bunları gözönünde bulundurarak şimdi hangi fonksiyonelliğin korunması gerektiğini düşünelim.Basit parse paketimizde sadece QDParser(Quick&DirtyParser) adında bir sınıf ve DocHandler adında bir arayüz bulunduracağız..QDParser kendi içinde sadece bir public statik metod bulunduracak ve bu parse(DocHandler,Reader) olacaktır.Bu bize sonlu durum makinesi(finite state machine) görevini sağlayacaktır. QDPARSER.JAVA package qdxml; import java.io.*; import java.util.*; /** SAX Parser’ın daha az fonksiyonellik ile oluşturulmuş versiyonu */ public class QDParser { private static int popMode(Stack st) { if(!st.empty()) return ((Integer)st.pop()).intValue(); else return PRE; } private final static int TEXT = 1, ENTITY = 2, OPEN_TAG = 3, CLOSE_TAG = 4, START_TAG = 5, ATTRIBUTE_LVALUE = 6, ATTRIBUTE_EQUAL = 9, ATTRIBUTE_RVALUE = 10, QUOTE = 7, IN_TAG = 8, SINGLE_TAG = 12, COMMENT = 13, DONE = 11, DOCTYPE = 14, PRE = 15, CDATA = 16; public static void parse(DocHandler doc,Reader r) throws Exception { Stack st = new Stack(); int depth = 0; int mode = PRE; int c = 0; int quotec = '"'; depth = 0; StringBuffer sb = new StringBuffer(); StringBuffer etag = new StringBuffer(); String tagName = null; String lvalue = null; String rvalue = null; Hashtable attrs = null; st = new Stack(); doc.startDocument(); int line=1, col=0; boolean eol = false; while((c = r.read()) != -1) { // \r, \r\n, ve \n, \n haline dönüştürüyoruz if(c == '\n' && eol) { eol = false; continue; } else if(eol) { eol = false; } else if(c == '\n') { line++; col=0; } else if(c == '\r') { eol = true;
c = '\n'; line++; col=0; } else { col++; } if(mode == DONE) { doc.endDocument(); return; // Metni almak için etiketlerdeyiz } else if(mode == TEXT) { if(c == '<') { st.push(new Integer(mode)); mode = START_TAG; if(sb.length() > 0) { doc.text(sb.toString()); sb.setLength(0); } } else if(c == '&') { st.push(new Integer(mode)); mode = ENTITY; etag.setLength(0); } else sb.append((char)c); // bitiş etiketini işliyoruz: } else if(mode == CLOSE_TAG) { if(c == '>') { mode = popMode(st); tagName = sb.toString(); sb.setLength(0); depth--; if(depth==0) mode = DONE; doc.endElement(tagName); } else { sb.append((char)c); } // CDATA işleme } else if(mode == CDATA) { if(c == '>' && sb.toString().endsWith("]]")) { sb.setLength(sb.length()-2); doc.text(sb.toString()); sb.setLength(0); mode = popMode(st); } else sb.append((char)c); // yorum işliyoruz -->. } else if(mode == COMMENT) { if(c == '>' && sb.toString().endsWith("--")) { sb.setLength(0); mode = popMode(st); } else sb.append((char)c); // Kök etiket elemanının dışındayız } else if(mode == PRE) { if(c == '<') { mode = TEXT; st.push(new Integer(mode)); mode = START_TAG; } // Ekarte edilen yapılar ... ?> , } else if(mode == DOCTYPE) {
if(c == '>') { mode = popMode(st); if(mode == TEXT) mode = PRE; } //< yakalandı ve tip belirleniyor } else if(mode == START_TAG) { mode = popMode(st); if(c == '/') { st.push(new Integer(mode)); mode = CLOSE_TAG; } else if (c == '?') { mode = DOCTYPE; } else { st.push(new Integer(mode)); mode = OPEN_TAG; tagName = null; attrs = new Hashtable(); sb.append((char)c); } // we varlık işleniyor <, », } else if(mode == ENTITY) { if(c == ';') { mode = popMode(st); String cent = etag.toString(); etag.setLength(0); if(cent.equals("lt")) sb.append('<'); else if(cent.equals("gt")) sb.append('>'); else if(cent.equals("amp")) sb.append('&'); else if(cent.equals("quot")) sb.append('"'); else if(cent.equals("apos")) sb.append('\''); // hex varlıklar da işlenebilir //else if(cent.startsWith("#x")) //sb.append((char)Integer.parseInt(cent.substring(2),16)); else if(cent.startsWith("#")) sb.append((char)Integer.parseInt(cent.substring(1))); // oluşturulmuş varlık tanımlarını buraya ekleyin else exc("Unknown entity: &"+cent+";",line,col); } else { etag.append((char)c); } //
. } else if(mode == SINGLE_TAG) { if(tagName == null) tagName = sb.toString(); if(c != '>') exc("Expected > for tag: <"+tagName+"/>",line,col); doc.startElement(tagName,attrs); doc.endElement(tagName); if(depth==0) { doc.endDocument(); return; } sb.setLength(0); attrs = new Hashtable(); tagName = null; mode = popMode(st); } else if(mode == OPEN_TAG) { if(c == '>') {
if(tagName == null) tagName = sb.toString(); sb.setLength(0); depth++; doc.startElement(tagName,attrs); tagName = null; attrs = new Hashtable(); mode = popMode(st); } else if(c == '/') { mode = SINGLE_TAG; } else if(c == '-' && sb.toString().equals("!-")) { mode = COMMENT; } else if(c == '[' && sb.toString().equals("![CDATA")) { mode = CDATA; sb.setLength(0); } else if(c == 'E' && sb.toString().equals("!DOCTYP")) { sb.setLength(0); mode = DOCTYPE; } else if(Character.isWhitespace((char)c)) { tagName = sb.toString(); sb.setLength(0); mode = IN_TAG; } else { sb.append((char)c); } // Bir eleman özelliğinin tırnaklı sağ kısmını işliyoruz } else if(mode == QUOTE) { if(c == quotec) { rvalue = sb.toString(); sb.setLength(0); attrs.put(lvalue,rvalue); mode = IN_TAG; // See section the XML spec, section 3.3.3 // normalizasyon. } else if(" \r\n\u0009".indexOf(c)>=0) { sb.append(' '); } else if(c == '&') { st.push(new Integer(mode)); mode = ENTITY; etag.setLength(0); } else { sb.append((char)c); } } else if(mode == ATTRIBUTE_RVALUE) { if(c == '"' || c == '\'') { quotec = c; mode = QUOTE; } else if(Character.isWhitespace((char)c)) { ; } else { exc("Error in attribute processing",line,col); } } else if(mode == ATTRIBUTE_LVALUE) { if(Character.isWhitespace((char)c)) { lvalue = sb.toString(); sb.setLength(0); mode = ATTRIBUTE_EQUAL; } else if(c == '=') { lvalue = sb.toString(); sb.setLength(0); mode = ATTRIBUTE_RVALUE; } else { sb.append((char)c); } } else if(mode == ATTRIBUTE_EQUAL) { if(c == '=') { mode = ATTRIBUTE_RVALUE;
} else if(Character.isWhitespace((char)c)) { ; } else { exc("Error in attribute processing.",line,col); } } else if(mode == IN_TAG) { if(c == '>') { mode = popMode(st); doc.startElement(tagName,attrs); depth++; tagName = null; attrs = new Hashtable(); } else if(c == '/') { mode = SINGLE_TAG; } else if(Character.isWhitespace((char)c)) { ; } else { mode = ATTRIBUTE_LVALUE; sb.append((char)c); } }
} if(mode == DONE) doc.endDocument(); else exc("missing end tag",line,col);
} private static void exc(String s,int line,int col) throws Exception { throw new Exception(s+" near line "+line+", column "+col); } } Bu parser DTD ve işlev komutlarını( gibi) sadece yorum olarak ele alacak ve bunların varlığı ile ilgilenmeyecektir. Biz DOCTYPE işlemi yapmayacağımızdan , parser’ımız oluşturulmuş varlık tanımlarını okuyamayacaktır.Bu durumda sadece &,<,>,&apos ve " gibi standard olanları kullanabileceğiz.Eğer bu bir problem yaratacak olursa o zaman tanımları genişletmek için kod eklentisi yapabilirsiniz.Alternatif olarak dokümanı önceden işleyerek oluşturulmuş varlık tanımlarını genişletilmiş metin karşılıkları ile değiştirerek dokümanı bu şekilde sınıfımıza yollayabilirsiniz. Herhangi bir özellik tanımı işlemeyeceğimizden , XML spesifikasyonunda tüm özellik tiplerinin CDATA olduğunu kabul edeceğiz.Böylece org.xml.sax.AttributeList yerine Java.util.Hashtable kullanabileceğiz.Bilindiği gibi java hashtable içerisinde sadece isim ve değer ikilileri bulunmaktadır ve tip daima CDATA olduğundan getType() metoduna ihtiyacımız olmamaktadır. Özellik tanımlarının yokluğunun tabiki etkileri de bulunmaktadır.Örneğin , parser varsayılan özellik değerleri sunamayacaktır.Ek olarak NMTOKENS tanımı ile otomatik olarak kaldırdığımız boşlukları parser’ımızda kaldıramayacağız.Bu konular XML dokümanı hazırlanırken ele alınmalıdır. Parser Fonksiyonelliği Parser’ın yetenekleri aşağıda sıralanmıştır. • • • • •
Tüm elemanların başlangıç ve bitiş etiketleri tanınmaktadır Özellikleri listelemektedir.Özellik değerleri tek veya çift tırnaklar ile kapatılabilmektedir. [CDATA [...] ] yapısı tanınmaktadır Standard varlıklar (&,<,>," ve &apos) ve numerik varlıklar tanınanacaktır. \r\n , \r ve \n gibi girdi satır düzenleyicileri tanınanacaktır.
Parser sadece minimum hata kontrolü yapmakta ve beklenmeyen bir düzen ile karşılaşıldığında bir exception vermektedir;bunun bir örneği bilinmeyen varlıklardır. Bu paketi nasıl kullanacağız? QDParser’ın kullanımı oldukça basit olacaktır.Öncelikle DocHandler arayüzü implement edilmelidir. DOCHANDLER.JAVA
package qdxml; import java.util.*; public interface DocHandler { public void startElement(String tag,Hashtable h) throws Exception; public void endElement(String tag) throws Exception; public void startDocument() throws Exception; public void endDocument() throws Exception; public void text(String str) throws Exception; } Bundan sonra config.xml adında bir xml dosyası parse edilebilir. DocHandler doc = new MyDocHandler(); QDParser.parse(doc,new FileReader("config.xml")); İzleyen kısımda tam DocHandler implementasyonu veren iki örnek bulabileceksiniz.Reporter adı verilen ilk DocHandler arayüzütüm olayları basitçe okudukça System.out ile raporlamaktadır.Bu implementasyon basitçe test edilebilir. REPORT.JAVA import qdxml.DocHandler; import qdxml.QDParser; import java.util.Hashtable; import java.util.Enumeration; import java.io.FileReader; /** Bu sınıf DocHandler sınıfı için yapılan en temel impelmentasyondur.Olaylar okundukça System.out ile bastırılmaktadır */ public class Reporter implements DocHandler { // DocHandler için sadece bir kopya oluşturuyoruz static Reporter reporter = new Reporter(); // DocHandler implementasyonu buradan itibaren başlamaktadır public void startDocument() { System.out.println(" dokuman baslangici"); } public void endDocument() { System.out.println(" dokuman bitisi"); } public void startElement(String elem,Hashtable h) { System.out.println(" bas elem: "+elem); Enumeration e = h.keys(); while(e.hasMoreElements()) { String key = (String)e.nextElement(); String val = (String)h.get(key); System.out.println(" "+key+" = "+val); } } public void endElement(String elem) { System.out.println(" son elem: "+elem); } public void text(String text) { System.out.println(" metin: "+text); } //DocHandler implementasyonu burada bitmektedir /** Kullanım: java Reporter [xml dosyası] */ public static void main(String[] args) throws Exception { for(int i=0;i<args.length;i++) reportOnFile(args[0]); } public static void reportOnFile(String file) throws Exception {
System.out.println("==============================="); System.out.println("dosya: "+file); // Burası DocHandler ile parse etmek istediğimiz dokümanı parse ettiğimiz koddur FileReader fr = new FileReader(file); QDParser.parse(reporter,fr); }
fr.close();
} İkinci ve daha gelişmiş örnekte ise Conf olarak adlandırdığımız örnektir.Bu örnek hafızadaki bir veri yapısındaki alanları güncellemektedir.Conf alanları ve config.xml de tanımları yapılan nesneleri berlirlemek için java.lang.reflect paketini kullanmaktadır.Eğer bu programı çalıştırırsanız hangi nesnelerin güncellendiği ve bunun nasıl yapıldığı ekrana bastırılacaktır.Eğer config dosyası bulunmayan alanları sorar ise bir hata mesajı bastırılacaktır. CONF.JAVA import java.util.Stack; import java.util.Hashtable; import java.util.Enumeration; import java.lang.reflect.Field; import qdxml.DocHandler; import qdxml.QDParser; import java.io.FileReader; /** QDParser ile ilgili diğer bir örnek.Bir veri yapısı xml elemanlarının java nesneleri ile örtüştürülmesi ile güncellenmektedir*/ public class Conf implements DocHandler { // Bir uzay gemisinin cihaz konfigürasyonunun kaydedilmesi için gereken sınıflar static class MissingSystem {} static class Engine { String spaceTimeSetting, spaceFoldRate; } static class Propulsion { Engine portWarpDrive = new Engine(); Engine starboardWarpDrive = new Engine(); } static class DefenseMechanism { String setting, frequency; } static class Defense { DefenseMechanism forceField = new DefenseMechanism(); DefenseMechanism ecm = new DefenseMechanism(); } static class Weapon { String power, setting; } static class CombatComputer { String subSystem, state; } static class Weapons { Weapon mainEnergyBeam = new Weapon(); Weapon secondaryEnergyBeam = new Weapon(); Weapon energyTorpedo = new Weapon(); CombatComputer combatComputer = new CombatComputer(); } static class AtmosphereSetting { String race, scent, level; } static class AtmosphereControl { AtmosphereSetting engineering = new AtmosphereSetting(); AtmosphereSetting bridge = new AtmosphereSetting(); AtmosphereSetting hydroponics = new AtmosphereSetting(); } static class LifeSupport {
AtmosphereControl atmosphere = new AtmosphereControl(); } static class ShipConfig { Weapons weapons = new Weapons(); Propulsion propulsion = new Propulsion(); Defense defense = new Defense(); LifeSupport lifeSupport = new LifeSupport(); } //Bir uzay gemisi konfigürasyonu için gereken tüm sınıfların tanımı yapıldı // Stack yapısı bir endElement ile karşılaşıldığında geri dönmemizi sağlamaktadır Stack stack; // şu an işlediğimiz nesne Object model = new ShipConfig(); public void text(String s) {} // Atamalar için reflection kullanılmaktadır // <weapons>bu andaki nesne alanlarının atanmasına başlanılacağını belirtir // <weapon setting="360cps"> aynı anlamdadır ancak setting adlı alana da bir değer atamak istediğimizi belirtir // Reflection buradaki işlemleri basitleştirdiği için kullanılmıştır public void startElement(String name,Hashtable h) { // İşlediğimiz nesne "model" oalrak adlandırılmaktadır.İlk işimiz isimdeki alana modeli atamaktır // durum çıktısı System.out.println(" Ayarlanıyor: "+name); if(stack.empty()) { stack.push(model); } else { stack.push(model); try { Field field = model.getClass().getDeclaredField(jname(name)); model = field.get(model); } catch(Exception ex) { // Varolmayan atama System.out.println("HATA: Alan bulunamadı "+ model.getClass().getName()+": "+name); model = new MissingSystem(); return; } } // İşlenen nesne alanlarının atanması Enumeration e = h.keys(); while(e.hasMoreElements()) { String key=null, val=null; try { key = (String)e.nextElement(); val = (String)h.get(key); key = jname(key); System.out.println(" ayarlıyor: "+key+" => "+val); Field field = model.getClass().getDeclaredField(key); // herşeyin metin olduğu kabul ediliyor(CDATA) field.set(model,val.toString()); } catch(Exception ex) { System.out.println("HATA: alan bulunamadı "+ model.getClass().getName()+": "+key); }
} } // bir önceki nesneye dön. public void endElement(String name) { model = stack.pop(); } public void startDocument() {
stack = new Stack(); } public void endDocument() { stack = null; } /** Bir xml stil ismini java stil ismine dönüştür Örnek: primary-weapon, primaryWeapon olmaktadır. */ public String jname(String s) { boolean ucase = false; StringBuffer sb = new StringBuffer(); for(int i=0;i<s.length();i++) { char c = s.charAt(i); if(c == '-') { ucase = true; } else if(ucase) { sb.append(Character.toUpperCase(c)); ucase = false; } else { sb.append(Character.toLowerCase(c)); } } return sb.toString(); } public static void main(String[] args) throws Exception { Conf c = new Conf();
}
// bu konfigürasn verisini config.xml i herhangi bir zamanda okuyarak yenileyebiliriz. // Alternatif olarak tüm konfigürasyonu değiştiren diğer bir xml dokümanını okuyabiliriz QDParser.parse(c,new FileReader("config.xml"));
} Paket özellikleri Bu paketi uygulamanız için dilediğiniz gibi değiştirebilirsiniz.QDParser sınıfı derlenip jar dosyasına konulduğunda yaklaşık 3 KB yer tutmaktadır.Bu ufak alan kısıtlamalı uygulamalar için yeterli ve XML spesifikasyonunun avantajlarını kullanabilme olanağı sunmaktadır. Bu örneğin çalışması için DocHandler ve QDParserqdxml adlı bir klasör içerisinde bulunmalı ve bu klasör ile aynı dizinde parse etmek istediğimiz xml dosyamız, ve Conf ve reporter gibi implementasyon sınıflarımız bulunmalıdır.
Java Teknolojisi ve XML XML İşleme için API’lara giriş Web servisleri ve e-ticaret platformlarındaki artan ilgi le geliştirme kutusunda XML birleşmektedir.Bugün Java ile XML tabanlı uygulamalr geliştirmek için 6 uzantı bulunmaktadır.
• • • • • •
,
Java
ile
XML İşleme için Java API (JAXP) XML/Java BAğı için Java API (JAXB) Uzun dönem JavaBean Kalıcılığı XML Mesajlama için Java API XML RPC için Java API (JAX RPC) XML Kaydı için Java API (JAXR)
Bu yazıda JAXP yi inceleyeceğiz.JAXP direk veya dolaylı olarak XML dokümanları ve ilintili Java teknolojisinin imkanlarını sunmaktadır.Bunlar ise şuşekilde listelenebilir.
•
SAX , XML için basit API
• • • •
DOM , W3C için Doküman Nesne Modeli XSLT , W3C den XML Stil Sayfası Dil Çevrimleri XPath , W3C den XML Yol Dili JDOM , Java için optimize edilmiş doküman nesne model API
Farklı XML İşleme Modellerine Genel Bakış Bir uygulamanın XML – tabanlı ya da diğer bir bakışla Web Servisi olması XML bakış açısı ile uygulamanın XML dokümanlarını kullanabilmesi,içerisindeki elde edilen veriye dayanan iş mantığının XML dokümanları ile sunulması için kullanılması demektir. 1.
2. 3.
XML girdi işleme • Parse etme ve kaynak dokümanın validasyonu • Gerekli bilginin yeri veya kaynak dokümandaki etiketlendirilmesi ile tanımlanması ve aranması • Gerekli bilginin yerinin saptanmasından sonra bilginin kullanılması • Elde edillen bilginin iş nesneleri ile örtüştürülmesi İş Mantığı • Girdi bilgisinin işlenip çıktı bilgisinin oluşturulma süreci XML Çıktı İşleme • DOM,JDOm ve benzeri ile jenerasyon için dokümanın modelinin oluşturulması • XSLT stil sayfalarının uyarlanması veya direk olarak XML serileştirmesi
SAX ve DOM en temel işleme modelleridir.Bir XML dokünmanının işlenmesi için SAX kullanmak için parser tarafından oluşturulan olayların ele alımı için gerekli metodlar kodlanmalıdır.DOM ile ise parser tarafından oluşturulan ağaç yapısı içerisinde kaynak dokümanda bilgiye ulaşmak için travers kodu yazılmalıdır.SAX parser bir olay akışı oluşturduğundan , yukarıda anlatılan 4 XML girdi işleme basamakları tek bir döngüde gerçekleştirilmelidir:Her yakalanan olay anında ele alınmalı ve olay ile bilg aktarılmalıdır.Dom kullanırken , XML giridi işleme ise en az iki döngüde gerçekleştirilmelidir:ilkinde DOM parser XML dokümanından bir DOM ağacı oluşturmalı ve daha sonra DOM ağacının içerisinde istenen bilgiye ulaşmak için yürüme işlemi geröekleştirilmelidir.Son kısım DOM ağacı hafızada kaldığı sürece istenildiği kadar tekrarlanabilmektedir.
Tablo 1: SAX ve DOM özellikleri SAX
DOM
Olay tabanlı modelleme
Ağaç veri yapısı
Seri giriş (olay akışı)
Rasgele giriş (hafıza veri yapısı)
Düşük hafıza kullanımı (sadece olaylar oluşturulur)
Yüksek hafıza kullanımı (doküman hafızaya yüklenmektedir)
Dokümanın kısımlarının işlenmesi (gerekli olayların yakalanması)
Dokümanın işlenmesi (hafızadaki veri yapsının işlenmesi)
Dokümanın sadece bir kere işlenmesi (olayların geçici akışı)
Birden fazla işleme (doküman hafızadadır)
XSLT , SAX ve DOM ‘ dan daha yüksek seviyeli bir işleme modelidir.XSLT,genellikle geliştiricinin kaynak dokümandaki belirli paternler ile karşılaşılınca uygulanacak kuralları(şablonları) kodlamasını gerektirir.Bu paternler ise XPath dili kullanılarak tanımlanmaktadır.XPath kaynak dokümanda bilginin saptanması ve elde edilmesi için kullanılmaktadır.SAX ve DOM Java kodu yazılmasını gerektirir fakat XSLT (motor çağrımından ayrı olarak) genellikle kendileri de XML dokümanları olan stil sayfalarının yazılması ile oluşturulur.DOM ve SAX programlamaya gore , XSLT programlama bir scripting olarak görülebilir.
Tablo 2: SAX, DOM ve XSLT işlem safhaları
İşleme Safhası
SAX
DOM
XSLT
XML girdi işleme Parse ve Validasyon
İçinde
İçinde veya SAX’a bağlı
SAX veya DOM ‘ a bağlı
Tanımlama/arama
Olayların olay ele alıcılar ile yakalanması
Ağacın ağaç yürümesi ile aranması
Xpath paternleri
Bilgi çıkarma
Olayların yakalanması
Özellik değerlerinin Özellik değerlerinin alınması,düğüm içeriği:API alınması,düğüm metodları içerikleri:XPath tanımları
Örtüştürme/Bağlama
Çıkarılan bilgiden iş nesnelerinin oluşturulması
Çıkarılan bilgiden iş nesnelerinin oluşturulması
Eğer yapılacaksa DOM veya SAX ile boruhattı oluşturulması
XML çıktı işleme İnşaa
Varsayılan bir destek yoktur ancak olay ele alıcılara dengeli ve sıralı bir metod çağrımı olulturularak gerçekleştirilebilir.
Modelin bir iç kısmıdır:API fabrika metodları
Modelin bir iç kısmıdır:XSL tanımları
Serileştirme
Varsayılan bir destek yoktur fakat özelleştirilmiş biro lay ele alıcı ile gerçekleştirilebilir
Spesifik destek impelementasyonu veya XSLT özdeşlik çevrimi
Modelin bir iç kısmıdır:XSL çıktı metod tanımı
XML işlemek için sunulan bazı API ‘ lar (DOM,XSLT) diğerlerinin üzerine kurularak daha yüksek seviyeli soyutlandırma ve böylece daha fazla güç sağlanabilir.Varolan her farklı teknoloji (SAX,DOM,XSLT,XPath ve JDOM) için performans ve programlama karşılaştırması açısından örnek programlar yazalım.Bu örneklerde uygulama alanı aynı olacak fakat çözüm değişik API ‘ la rile sağlanacaktır. Örnek Uygulama Alanı Bu örneklerdeki XML dokümanları aynı DTD ve XML Schema’ya sahiptir.Bu schema ‘ lar bir satranç tahtası konfigürasyonunu göstermektedir.
Her program satranç tahtası konfigürasyonunu basit ve okunabilir bir formatta bastıracaktır. Aşağıda tahta konfigürasyonunun XML ve düz metin olarak iki göstermi verilmiştir.Düz metin gösterimi birinciden , verilecek olan programların çıktılarından elde edilmiştir. Satranç tahtası konfigürasyonunun XML gösterimi <WHITEPIECES> Satranç tahtası konfigürasyonunun düz metin gösterimi White White White White White White
king: G1 bishop: D6 rook: E1 pawn: A4 pawn: B3 pawn: C2
White White White Black Black Black Black
pawn: F2 pawn: G2 pawn: H5 king: B6 queen: A7 pawn: A5 pawn: D4
İşlenen XML Dokümanları İki örnek XML girdi dokümanı oluşturulmuştur:
• •
Bir DTD ‘ye uyan XML dokümanları Eşdeğer bir XML Schema ‘ya uyan XML dokümanları
XML Schema spesifikasyonunu destekleyen az sayıda parser mevcut olduğundan,örnek programların çoğu DTD ‘ ye dayanan XML dokümanını kullanacaklardır.İkinci doküman kümesi ise sadece DTD ve Schema performans karşılaştırması için kullanılacaktır. DTD Tabanlı Dokümanlar Örnek programlara girdi iin kullanılan XML dokümanlarının düzenini iki DTD tanımlamaktadır.
• •
Tek satranç tahtası konfigürasyonunu tanımlayan bir DTD İlkine dayalı olarak bir satranç tahtası konfigürasyonları kğmesini tanımlayan diğer bir DTD
Bir satranç tahtası konfigürasyonu için DTD
KING (POSITION)> QUEEN (POSITION)> BISHOP (POSITION)> ROOK (POSITION)> KNIGHT (POSITION)> PAWN (POSITION)>
İzleyen DTD ise önceki tanımı kullanarak CHESSBOARDS elemanının çocuğu olma niteliği taşıyan satranç tahtaları tanımlamasını yapmaktadır. Birden fazla satranç tahtası konfigürasyonu için DTD %chessboard; Satranç tahtası konfigürasyonlarının sayısı sınırsızdır ve tek bir dokümanda istenildiği kadar satranç tahtası konfigürasyonu kullanılabilir. DTD tanımına uyan bir XML dokümanı
<WHITEPIECES> ... Örnek programlar Yazacağımız programlar SAX,DOM ve XSL Çevrim Motoru ‘na dayalı farklı implementasyonlar ile etkileşmek için JAXP kullanmaktadır. Java API for XML Processing (JAXP) JAXP uygulamaların herhangi bir XML işleyici implementasyonundan bağımsız olarak XML dokümanlarını parse etme ve çevirmeye yarayan bir API ‘dır.Bu sayede uygulamaları etkilemeden XML işleyici implenetasyonları değiştirilebilmektedir.JAXP 1.1 SAX versiyon 2.0 , DOM Seviye 2.0 ve XSLT 1.0 standardlarını desteklemektedir. JAXP farklı XML parser ve XSLT motoru implementasyonlarını oluşturmak ve çağırmak için kullanılmıştır.API yeni SAX parser,DOM doküman oluşturucu ve stil sayfası motorları oluşturmak için fabrika dizayn paternlerini kullanmaktadır.Aşağıda SAX,DOM ve XSLT kullanrak bir XML dokümanı işleme örnekleri verilmiştir. JAXP ile SAX API kullanmak için
• • • • •
Yeni bir SAX Parser Fabrikası oluşturulmalı Fabrika ayarlanmalı Fabrikadan yeni bir parser oluşturulmalı Parser’ın doküman ele alıcısı,hata yakalayıcısı,DTD ele alıcısı ve varlık çözümleyicisi atanmalı XML dokümanları parse edilmelidir
JAXP kullanarak bir SAX Parser çağrımı ve SAX olayları akışı halinde dokümanın parse edilmesi import org.xml.sax.*; import org.xml.sax.helpers.*; import javax.xml.parsers.*; boolean validating; String fileToProcess; ... SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(validating); SAXParser parser = factory.newSAXParser(); ... parser.parse(fileToProcess, new HandlerBase() { ... // Dokümanın bir SAX olayları şeklinde parse etmek için HandlerBase implementasyonu }); ...
JAXP ile DOM kullanımı için tipik basamaklar • Yeni bir DOM doküman oluşturma fabrikası yaratılmalı • Fabrika ayarlanmalı • Fabrikadan yeni bir doküman oluşturucu yaratılmalı • Parser’ın hata yakalayıcısı ve verlık çözümleyisicisi atanmalı • DOM ağacının oluşturulması için XML dokümanı parse edilmelidir JAXP ile bir doküman oluşturucu çağrımı,parse etme ve dokümanın bir DOM ağacı olarak işlenmesi import org.w3c.dom.*; import javax.xml.parsers.*; boolean validating; String fileToProcess; ... DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(validating); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setErrorHandler(new ErrorHandler() { ... }); ... Document document = builder.parse(fileToProcess); ... // Dokümanın bir DOM ağacı olarak işlenmesi JAXP , XSL Çevrimleri için kullanıldığında,yapılacak olan işlemler , DOM ve SAX ta olduğundan fazla farklı değildir.
• • •
• •
Yeni bir çevrim fabrikası yaratılmalı Fabrika ayarlanmalı Yeni çevirici fabrikadan belirli bir stil sayfası ile yaratılmalı Hata dinleyici ve URI çözümleyici atanmalı Stil ayfası XML uygulanmalıdır
dokümanlarına
DOM
ağaçları,SAX
olayları
veya
çıktı
akıntısı
için
JAXP ile bir XSLT motoru çağrımı ve dokümanın XSLT stil sayfası ile işlenmesi;API stil sayfası motoruna paramere geçişini desteklemektedir. import javax.xml.transform.*; String styleSheetFile; String fileToProcess; OutputStream out; Properties properties; ... TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer( new SAXSource(new InputSource(styleSheetFile))); for (Enumeration i = properties.propertyNames(); i.hasMoreElements();) { String name = (String) i.nextElement(); transformer.setParameter(name, "\'" + properties.getProperty(name) + "\'"); } transformer.transform( new SAXSource(new InputSource(fileToProcess)), new StreamResult(out)); ... Örnek Programların Ortak Yapısı Tüm örnek programların kullanım esnekliği açısından ortak bir yapısı buşunmaktadır.Bu programlar JAXP kullanımı yukarıda bahsedilen basamakları izlemekte v eek olarak aynı dokümanı birçok çalışma zamanında birçok defa işlemek için döngüler içermektedirler.Her çalışmada bir fabrika bir parser veya stil sayfası yaratmak için kullanılmaktadır ve bu XML dokümanının birden fazla defa işlenmesine olanak tanımaktadır.Kaynak
dokümanın DTD veya XML Schema lara olan geçerlemesi program çağrımı sırasında setValidating metodu ile gerçekleştirilmektedir böylece geçerleme yapan veya yapmayan bir parser oluşturulabilmektedir. Örnek programların yapısı örneği import org.xml.sax.*; import org.xml.sax.helpers.*; import javax.xml.parsers.*; public class ChessboardSAXPrinter { private SAXParser parser; public ChessboardSAXPrinter(boolean validating) throws Exception { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setValidating(validating); parser = factory.newSAXParser(); ... return; } public void print(String fileName, PrintStream out) throws SAXException, IOException { ... parser.parse(fileName, ...); return; } public static void main(String[] args) { ... for (int k = 0; k < r; k++) { // r: number of runs ChessboardSAXPrinter saxPrinter = new ChessboardSAXPrinter(validating); long time = System.currentTimeMillis(); for (int i = 0; i < n; i++) { // n: number of document processed per run saxPrinter.print(args[0], out); } System.err.print( (((double) (System.currentTimeMillis() - time)) / 1000 / n) + "\t"); } ... }
}
JAVA ile JAXP Parser Örnek Programları 16/08/2003 SAX Örnek Programı SAX önceki bölümlerde belirttiğimiz gibi bir olay tabanlı model kullanmakta ve kaynak dokümanın bir olaylar zinciri halinde işlenmesini gerektirmektedir.Bu olaylar metod çağrımları sırasında oluşmaktadır.Olaylar , doküman elemanları ile aynı şekilde yuvalanmışlardır bundan dolayı anlık bir doküman modeli bulunmamaktadır.Hafıza kullanmı düşük iken programlama modeli karmaşık olabilmektedir ve bu özellikle dokümanın yapısı ile uygulamanın veri yapısının uyuşmama durumunda daha da karmaşıklaşmaktadır.Olayların geçici bir akışı gerçekleştirildiğinden SAX API , doküman modelinin düzenlenmesi veya birden fazla işlenmesi gereken durumlarda kullanılamaz. SAX API birden fazla arayüz tanımlamaktadır.
•
org.xml.sax.Parser arayüzü
o o
Bir XML dokümanını parse eder Bir uygulamanın aşağıdakileri kaydetmesini sağlar
Bir doküman olay ele alıcısı
•
•
•
Bir hata ele alıcısı Bir DTD ele alıcısı Varlık çözümleyicisi
org.xml.sax.DocumentHandler arayüzü (doküman olayları)
o o o o o
Bir dokümanın başlangıcı veya bitişi Bir elemanın başlangıcı veya bitişi Karakter verisi Eleman içeriğinde ihmal edilebilir boşluklar İşleme komutu
org.xml.sax.ErrorHandler arayüzü
o o o
Kurtarılabilir hata Sonlandırıcı hata Uyarı
org.xml.sax.DTDHandler arayüzü
o o
Bir uyarı tanımlama olayı Parse edilmemiş varlık tanım olayı
•
org.xml.sax.EntityResolver arayüzü (Dış varlık referanslarının çözümlenmesi)
•
org.xml.sax.HandlerBase arayüzü (Önceki arayüzlerin varsayılan implementasyonları)
Bir uygulama gerekli olayları yakalayıp işlemek için en az bir DocumentHandler sunmalıdır.
Aşağıda verilen örnek program HandlerBase arayüzünü ve özellikle startElement çağrım metodunu implemente etmektedir.Bir SAXParserFactory yeni bir SAXParser oluşturmak için kullanılmaktadır.HandlerBase arayüzünün implementasyonu ve XML kaynak dokümanının yolu parser’a gönderilmektedir.Parse edilirken startElement metodu her etiket için çağrılmaktadır. import org.xml.sax.*; import org.xml.sax.helpers.*; import javax.xml.parsers.*; public class ChessboardSAXPrinter { private SAXParser parser; private PrintStream out; public class ChessboardHandler extends HandlerBase {
private boolean whitePiece = false; public void startElement(String name, AttributeList attrs) { if (name.equals("WHITEPIECES")) { whitePiece = true; } else if (name.equals("BLACKPIECES")) { whitePiece = false; } else if (name.equals("KING") || name.equals("QUEEN") || name.equals("BISHOP") || name.equals("ROOK") || name.equals("KNIGHT") || name.equals("PAWN")) { out.print((whitePiece ? "White" : "Black") + " "+ name.toLowerCase() + ": "); } else if (name.equals("POSITION")) { if (attrs != null) { out.print(attrs.getValue("COLUMN")); out.println(attrs.getValue("ROW")); } } return; } ...
} ...
}
Parse edilirken startElement metodu izleyen başlangıç etiketi olaylarını yakalamaktadır.
1. 2. 3.
Yuvalanmış parçaları izlemek için BLACKPIECES ve WHITEPIECES Parça adı ve rengini bastırmak için KING,QUEEN,BISHOP,ROOK,KNIGHT,PAWN
POSITION ROW ve COLUMN elemanları ile parçanın pozisyonu için Diğer olaylar ele alınmamıştır ancak gerçek bir uygulama endElement,characters gibi olayları da ele alarak olay akışını daha karmaşık bir sistem ile iş nesnelerine aktarabilmekte ve daha sonra bunlara iş mantığını uygulayabilmektedir.SAX kullanmak zahmetli fakat hızlı bir tekniktir. DOM Örnek Programı DOM , platform ve dilden bağımsız bir arayüzdür ve program ve script’lerin dokümanın içeriğine,yapısına ve stiline dinamik olarak giriş yapmasını ve güncellemesine izin vermektedir.DOM esasta bir ağaç veri yapısıdır ve bu yapıya erişim ve düzenlemeyi gerçekleştirmek için bir metodlar kümesi barındırmaktadır.Hafızada bulunan bir veri yapısı olduğundan , hafıza kullanımı SAX’a göre oldukça yüksektir fakat doküman modeli rasgele erişilebilir durumdadır ve birden fazla kez işlenebilir. DOM API bir XML dokümanındaki her varlık için arayüzler tanımlamaktadır.
•
org.w3c.dom.Node arayüzü ;doküman ağacındaki bir düğümdür
o o o
Çocuk düğümlere giriş,ekleme,çıkarma ve değiştirmek için metod tanımları Parent düğüm e giriş için metodlar Dokümana giriş için metodlar tanımlıdır
•
org.w3c.dom.Document arayüzü tüm XML dokümanını tanımlayan bir düğümdür
•
org.w3c.dom.Element arayüzü bir XML elemanını tanımlayan düğümdür
•
org.w3c.dom.Text arayüzü bir XML elemanının metin içeriğini tanımlayan düğümdür.
Uygulama iş mantığını direk olarak DOM ağacına uygulayabileceği gibi ilk başta gerkli bilgiyi ağaçtan iş nesnelerine alarak daha sonra işleme geçebilir.
Aşağıdaki program bir satranç tahtası konfigüsaryonunu tanımlayan XML dosyasını parse edip hafızaya almak için DOM API kullanmaktadır.Daha sonra sonuç olarak çıkan DOM ağacının içerisinde yürümekte ve aynı tahta konfigürasyonunu metin düzeninde bastırmaktadır. import org.w3c.dom.*; import org.xml.sax.*; import javax.xml.parsers.*; public class ChessboardDOMPrinter { private DocumentBuilder builder; public void print(String fileName, PrintStream out) throws SAXException, IOException { Document document = builder.parse(fileName); NodeList nodes_i = document.getDocumentElement().getChildNodes(); for (int i = 0; i < nodes_i.getLength(); i++) { Node node_i = nodes_i.item(i); if (node_i.getNodeType() == Node.ELEMENT_NODE && ((Element) node_i).getTagName() .equals("CHESSBOARD")) { Element chessboard = (Element) node_i; NodeList nodes_j = chessboard.getChildNodes(); for (int j = 0; j < nodes_j.getLength(); j++) { Node node_j = nodes_j.item(j); if (node_j.getNodeType() == Node.ELEMENT_NODE) { Element pieces = (Element) node_j; NodeList nodes_k = pieces.getChildNodes(); for (int k = 0; k < nodes_k.getLength); k++) { Node node_k = nodes_k.item(k); if (node_k.getNodeType() == Node.ELEMENT_NODE) { Element piece = (Element) node_k; Element position = (Element) piece.getChildNodes().item(0); out.println((pieces.getTagName() .equals("WHITEPIECES") ? "White " : "Black ") + piece.getTagName().toLowerCase() + ": " + position.getAttribute("COLUMN") + position.getAttribute("ROW")); } } } } }
} return;
}
}
Bu program DocumentBuilder tarafından oluşturulan DOM ağacından yürüyerek ,
1. 2. 3. 4.
Tüm CHESSBOARD elemanlarını almakta Her CHESSBOARD elemanı için BLACKPIECES ve WHITEPIECES alt elamanlarını almakta Her B ve W elemanları için KING,QUEEN,BISHOP,ROOK,KNIGHT ve PAWN alt elemanlarını almakta Ve bu elemanların her biri için renk,isim ve pozisyon bastırılmaktadır.
Aşağıdaki alternatif implementasyon algoritma olarak aynıdır ancak elemanları isim ile almaktadır.Bu metod tüm alt ağaçta elemanlara bakmakta olduğundan daha az efektif olabilir.getElementsByTagName metodu belirli bir isimdeki tüm çocukları elde ettiğinden tüm POSITION elemanları doküman kökünden itibaren toplanabilir ve her eleman için parçanın ismi ve rengi bastırılabilir. public void print(String fileName, PrintStream out) throws SAXException, IOException { Document document = builder.parse(fileName); NodeList positions = document.getElementsByTagName("POSITION"); for (int i = 0; i < positions.getLength(); i++) { Element position = (Element) positions.item(i); Element piece = (Element) position.getParentNode(); Element pieces = (Element) piece.getParentNode(); out.println( (pieces.getTagName().equals("WHITEPIECES") ? "White " : "Black ") + piece.getTagName().toLowerCase() + ": " + position.getAttribute("COLUMN") + position.getAttribute("ROW")); } return; } JDOM Örnek Programı JDOM bir XML dokümanının Java ile gösterimidir.JDOM kolay ve verimli okunabilirlik,düzenleme ve yazma için dokümana bir gösterim sunar.JDOM yüzeysel bir API’dır , az yer kaplar ve hızlıdır ve Java programcıları için optimize edilmiştir.DOM ve SAX için bir alternatiftir fakat DOM ve SAX ile entegre durumdadır. JDOM kullanarak bir XML dokümanını parse eden ve hafızaya yükleyen program sonuç JDOM dokümanı içerisinde yürüyerek aynı konfigürasyonu bir metin dosyası halinde bastırmaktadır.Bir SAXBuilder , XML kaynak dokümanından JDOM dokümanı oluşturmak için kullanılmaktadır.Varsayılan değer olarak bir JDOM SAXBuilder içerisinde bir SAXParser oluşturmak için JAXP e dayanır. import org.jdom.*; import org.jdom.input.*; import org.xml.sax.*; public class ChessboardJDOMPrinter { private static boolean verbose = false; private SAXBuilder builder; public ChessboardJDOMPrinter(boolean validating) throws Exception { builder = new SAXBuilder(); builder.setValidation(validating); ... return; } public void print(String fileName, PrintStream out) throws JDOMException { Document document = builder.build(fileName);
Element root = document.getRootElement(); List chessboards = root.getChildren("CHESSBOARD"); for (int i = 0; i < chessboards.size(); i++) { Element chessboard = (Element) chessboards.get(i); String[] pieceSetTags = { "WHITEPIECES", "BLACKPIECES" }; for (int j = 0; j < pieceSetTags.length; j++) { List pieceSets = chessboard.getChildren(pieceSetTags[j]); for (int k = 0; k < pieceSets.size(); k++) { Element pieceSet = (Element) pieceSets.get(k); String[] pieceTags = { "KING", "QUEEN", "BISHOP", "ROOK", "KNIGHT", "PAWN" }; for (int l = 0; l < pieceTags.length; l++) { List pieces = pieceSet.getChildren(pieceTags[l]); for (int m = 0; m < pieces.size(); m++) { Element piece = (Element) pieces.get(m); Element position = piece.getChild("POSITION"); out.println( (j == 0 ? "White " : "Black ") + pieceTags[l].toLowerCase() + ": " + position.getAttributeValue("COLUMN") + position.getAttributeValue("ROW")); } } } } } return;
} ...
}
Bu program DOM örnek programına oldukça yakındır.Program XML dokümanından oluşturulan JDOM ağacından yürümektedir.
1. 2. 3. 4.
Tüm CHESSBOARD elemanlarını almakta Her CHESSBOARD elemanı için BLACKPIECES ve WHITEPIECES alt elemanlarını almakta Her B ve W elamanı için KING,QUEEN,BISHOP,ROOK,KNIGHT ve PAWN alt elemanlarını almakta Bunların herbiri için POSITION alt elemanını almakta ve rengini,ismini ve pozisyonunu bastırmaktadır.