| « Tasdix, Türk Blog Yazarları ile buluşuyor | eski arkadaş "grid" » |
Xml Namespaces
Konuya yabancı olanlar için xml namespace'leri "allahın belası prefixler ve web adresleri" olarak gözükmesi normaldir. (kendimden biliyorum)
Konuya başlangıç olması için örneğin;
XML:
<person> | |
<name/> | |
<surname/> | |
</person> |
şeklinde bir xml düşünelim. Bu bir web servisinin kullandığı bir tanım yada bir uygulamaya entegrasyon için kullanılıyor olabilir.
sorun person içerisine kendinize özgü bir alan (mesela yaşı belirtecek olan bir age şeklinde bişey eklediğinizde ortaya çıkar. yani;
XML:
<person> | |
<name/> | |
<surname/> | |
<age/> | |
</person> |
age element'ini eklediğinizde kullandığınız webservisi yada uygulamanın "age diye bir şey bilmiyorum ben!" diye bağırmaması için dua etmeye başlayabilirsiniz.
xml namespace'leri tam bu aşamada devreye girerek aynı xml içerisinde farklı amaçlar/alanlar tanımlamanıza imkan verir. yani;
XML:
<person xmlns="http://mynicewebservice.org"> | |
<name/> | |
<surname/> | |
<age xmlns="http://noyell.org"/> | |
</person> |
şeklinde person ve içindeki namespace verilmemiş tüm elementlerin "http://mynicewebservice.org" adresine ait olduğunu ama age element'inin farklı bir alana ait olduğunu belirtebilirsiniz.
verilen adresler gerçek bir web adresi olmak zorunda değildir ancak teoride o namespace için kullanılan schema'ları içeren bir xsd göndermesi beklenir. bunu yaparsanız Visual Studio gibi renkli ortamlarda intellisense gibi olayların otomatik çalışmasını sağlayabilirsiniz.
neden prefix?
aynı namespace'i birden fazla kullanılması durumunda xml içerisinde yüzlerce xmlns="http://mynicewebservice.org" yazmak yerine bunu kısa yoldan yazacak bir metod kullanmak gerekir. yani;
XML:
<xx:person xmlns:xx="http://mynicewebservice.org"> | |
<xx:name/> | |
<xx:surname/> | |
<yy:age xmlns:yy="http://noyell.org"/> | |
</xx:person> |
böylece xx prefix'i verilmiş tüm node'lar söylediğiniz alana ait olur.
bunun daha derli toplu olmasını istiyorsanız root element içerisinde tüm namespace'leri tanımlayarak daha temiz bir xml elde edebilirsiniz.
yani;
XML:
<xx:person xmlns:xx="http://mynicewebservice.org" xmlns:yy="http://noyell.org"> | |
<xx:name/> | |
<xx:surname/> | |
<yy:age/> | |
</xx:person> |
yazdığınız prefix'lerin hiç bir önemi yoktur, önemli olan namespace url'sinin unique olmasıdır. bu xml'i okuyacak olan sistem sizin verdiğiniz prefix'lerle ilgilenmez bile, onun için önemli olan namespace için verdiğiniz (web adresi) uri'dir. kendine ait olan veriyi bu namespace içerisinde okuyacağı için sizin gönderdiğiniz age element'ini görmezden gelecektir. yani;
XML:
<zz:person xmlns:zz="http://mynicewebservice.org" xmlns:yy="http://noyell.org"> | |
<zz:name/> | |
<zz:surname/> | |
<yy:age/> | |
</zz:person> |
örneği bir önceki xml ile tamamen aynıdır. prefix sadece namespace'i tanımlamak için kullanılır.
ne sorun yaşarım?
gelelim "allahın belası" kısmına,
öncelikle bu xml'i okuyacak sistemin namespace tanımlarına dikkat ediyor olması gerekli, eğer bu tür şeyleri umursamayan bir sistemse "ne demek istiyorsun?" şeklinde hata mesajları verecektir.
xml içerisindeki verileri sorgulamak için kullanılan xpath'ler üzerinde namespace tanımını yapmış olmanız gereklidir.
örneğin;
Code:
XmlDocument doc; | |
| |
doc.DocumentElement.SelectSingleNode("/*/xx:person/yy:age",manager); |
şeklinde bir kod "xx" prefix'ine ait bir namespace tanımlamadığınıza dair bir hata verecektir. bunun yerine;
Code:
XmlDocument doc; | |
XmlNamespaceManager manager; | |
| |
manager.AddNamespace("qq","http://mynicewebservice.org"); | |
manager.AddNamespace("ww","http://noyell.org"); | |
| |
doc.DocumentElement.SelectSingleNode("/*/qq:person/ww:age",manager); |
şeklinde xml element'lerine erişebilirsiniz. xml içerisindeki prefix'i canınızın istediği şekilde verebilirsiniz, yeterki namespace'ler aynı olsun.
ne gerek var?
örnekteki gibi ufak xml dosyaları çalıştığınız sürece namespace tanımlarına zorunlu olmadıkça ihtiyaç duymazsınız. ancak xml tanımlarınız genişlemeye başladığında aynı element isimlerinin birbirleri ile çakışması, hangi element'in nereye ait olduğunu tanımlamada zorlanmaya başlarsınız.
buna göre 2 seçim şansınız vardır, ya şimdiden namespace'lere dikkat ederek kod yazabilirsiniz yada benim boyum ufak kalacak diyerek bunların hiç birine aldırış etmeyebilirsiniz. iki yolda mübahtır, hangisini isterseniz.
1 comment
namespace cicidir.