https://buraksenyurt.com/Burak Selim Şenyurt - XML2024-03-14T08:25:19+00:00Matematik Mühendisi Bir Bilgisayar Programcısının NotlarıBurak Selim SenyurtBlogEngine.Net Syndication Generatorhttps://buraksenyurt.com/opml.axdBurak Selim SenyurtMatematik Mühendisi Bir Bilgisayar Programcısının Notlarıtr-TRBurak Selim Şenyurt0.0000000.000000https://buraksenyurt.com/post/XML-Verilerini-XSD-ile-Yonetimli-Kod-Uzerinden-Dogrulamak-bsenyurt-com-danXML Verilerini XSD ile Yönetimli Kod Üzerinden Doğrulamak2006-09-01T09:00:00+00:00bsenyurt<p>Değerli Okurlarım Merhabalar,</p>
<p>Xml içeriğini kullandığımız pek çok platformda, verinin belirli kurallara göre yazılmış olmasını istediğimiz durumlar söz konusu olabilir. Bu durum özellikle, farklı platformlar arasında taşınacak Xml tabanlı verilerin aynı kurallar dizisine uygun olacak şekilde kullanılması istendiği durumlarda karşımıza çıkmaktadır. Xml verilerinin belirli kurallara göre doğruluğunun tespitinde şu anda <strong>DTD (Document Type Definitions), XDR (Xml Data Reduced)</strong> ve <strong>XSD (Xml Schema Definitions) </strong>gibi teknolojilerden yararlanılmaktadır.</p>
<p>Bu teknolojiler yardımıyla bir Xml verisi içerisindeki elemanlar üzerinde çeşitli kurallar tanımlayabiliriz. Örneğin tutulan veri tiplerini sınırlayabilir, Xml ağacının yapısını tanımlayabiliriz vb. Böylece verilerin tutarlılığınıda sağlamış oluruz. Günümüzde, Xml verilerinin doğrulanması için kullanılan en yaygın teknoloji XSD ' dir. XSD' yi daha önceki türevi olan XDR' ın mükemmelleştirilmiş hali olarakta düşünebiliriz. Zaten WC3' da XSD şemalarının kullanılmasını önermektedir. Biz bu makalemizde .Net tarafında yer alan yönetimli tipleri (Managed Types) kullanarak Xml verilerini XSD ile çarpıştırarak doğrulama işlemlerini nasıl yapabileceğimizi incelemeye çalışacağız. İlk olarak aşağıdaki gibi bir Xml içeriğimiz olduğunu düşünelim.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false"><?xml version="1.0" encoding="utf-8"?>
<Dukkanim>
<Kitap ID="1000">
<Adi>Her Yönüyle C#</Adi>
<Fiyat>Elli YTL</Fiyat>
<StokDurumu>40</StokDurumu>
<Yazarlar>
<Yazar>Sefer Algan</Yazar>
</Yazarlar>
<BasimTarihi>10/11/2003</BasimTarihi>
<Aciklama>C# ile ilgili yazılmış en iyi Türkçe kaynaklardan birisidir. </Aciklama>
</Kitap>
<Kitap ID="1001">
<Adi>Kahraman Asker</Adi>
<Fiyat>30</Fiyat>
<StokDurumu>Bin Adet</StokDurumu>
<Yazarlar>
<Yazar>Anonim</Yazar>
</Yazarlar>
<BasimTarihi>10/11/2004</BasimTarihi>
<Aciklama>C# ile ilgili yazılmış en iyi Türkçe kaynaklardan birisidir. </Aciklama>
</Kitap>
</Dukkanim></pre>
<p>Bu Xml içeriğinde Kitaplar ile ilgili bir takım bilgileri tutmaktayız. Örneğin Kitabın adını, fiyatını, stoktaki durumunu, basım tarihi vb. Bu Xml dökümanını herhangibir tarayıcı yardımıyla açtığımızda geliştiriciler için okunabilir ve anlaşılabilir bir içerik elde ederiz.</p>
<p><img src="/makale/images/mk173_1.gif" alt="" width="610" height="469" border="0" /></p>
<p>Lakin bu Xml içeriğinin platformlar arasında taşındığını ve işlendiğini düşündüğümüzde hataya neden olacak pek çok problemin olduğunu görebiliriz. Örneğin Fiyat alanlarında bir standart yoktur. Öyleki ilk Kitap elemanı (element) içerisinde Fiyat değeri Elli YTL olarak string bazlı yazılmışken, ikinci Kitap elemanındaki Fiyat elemanının değeri 30 olarak sayısal belirtilmiştir. Başka bir deyişle Fiyat alanının aslında uygun bir veri tipi olma zorunluğu yoktur. Dolayısıla bu Xml dökümanını alıp fiyatlar üzerinde sayısal işlemler yapacak olan bir uygulama kodu sorunlar ile karşılaşacaktır.</p>
<p>Benzer durum StokDurumu elemanı içinde geçerlidir. Bu tip veri uyuşmazlıklarını şemalarda yapacağımız tanımlamalar ile düzeltebiliriz. Diğer taraftan dikkat ederseniz her Kitap elemanı içerisinde Yazarlar isimli bir eleman bulunmaktadır ki bu elemanda en az bir Yazar elemanını içermelidir. Bu da bir kural olarak şema bilgisi içerisine alınabilir. XSD şemalarını sıfırdan herhangibir editor kullanmadan yazmak her zaman keyfi verici bir iş olmayabilir. Lakin Vs.Net 2003 sürümünden bu yana, görsel olaraktan XSD şemalarını kolayca hazırlayabilmemizi sağlayan bir arabirim sunmaktadır. Buna göre yukarıdaki Xml dökümanımız için aşağıdaki gibi bir XSD şemasını kolayca hazırlayabiliriz. <em>(XSD' nin öğrenilebilecek daha çok özelliği olduğundan ve makalemizin sınırlarını aştığından çok fazla derinine inmeyeceğiz.)</em></p>
<p><img src="/makale/images/mk173_2.gif" alt="" width="638" height="233" border="0" /></p>
<pre class="brush:xml;auto-links:false;toolbar:false" contenteditable="false"><?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Dukkanim">
<xs:complexType>
<xs:sequence>
<xs:element name="Kitap" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Adi" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="Fiyat" type="xs:double" minOccurs="1" maxOccurs="1"/>
<xs:element name="StokDurumu" type="xs:integer" minOccurs="1" maxOccurs="1"/>
<xs:element name="Yazarlar" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="Yazar" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="BasimTarihi" type="xs:dateTime" minOccurs="1" maxOccurs="1" />
<xs:element name="Aciklama" type="xs:string" minOccurs="1" maxOccurs="1" />
</xs:sequence>
<xs:attribute name="ID" type="xs:integer" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema></pre>
<p>İlk olarak şema dosyamızda belirttiğimiz kuralları kısaca incelemeye çalışalım. Örneğin Adi, Fiyat, StokDurumu, Yazarlar, BasimTarihi, Aciklama gibi elemanlardan sadece ve yanlız bir adet girilebileceği belirtilmektedir. Bu kural <strong>minOccurs</strong> ve <strong>maxOccurs</strong> isimli özellikler ile belirtiliyor. Dolayısıyla Yazarlar isimli elemanımız, kendi içerisinde en az bir olacak şekilde istenildiği kadar (<strong>unbounded</strong> sayesinde) Yazar elemanı içerebilir. XSD dökümanımız içerisinde yer alan her eleman (ve hatta ID isimli attribute-nitelik) için ayrı veri tipi tanımlamaları yapılmıştır. Örneğin ID isimli attribute (nitelik) integer tipinden olmalıdır. Fiyat isimli elemanımız double türünden olmalıdır vb.</p>
<p>Peki bu ve benzeri şema bilgisini(bilgilerini) kullanarak yazdığımız Xml içeriğini yönetimli kod tarafından (managed-code) nasıl denetleyebiliriz? .Net 2.0 içerisinde bu tip işlemler için getirilmiş yeni tipler vardır. Bunlar <strong>XmlReaderSettings</strong>, <strong>XmlSchemaSet</strong> isimli tiplerdir. Konuyu daha iyi anlayabilmek için örnek kodlar ile devam etmemizde fayda olduğu kanısındayım. Aşağıdaki kod parçasında bir Asp.Net formu üzerinde, Dukkan.xml isimli Xml dökümanının Dukkan.xsd isşmli xml şema dökümanı ile doğrulanmasının nasıl yapılabileceği gösterilmektedir.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
StringBuilder hatalar;
protected void Page_Load(object sender, EventArgs e)
{
string xmlFile = Server.MapPath("Dukkan.xml");
string XSDFile =Server.MapPath( "Dukkan.XSD");
hatalar = new StringBuilder();
XmlReaderSettings xrs = new XmlReaderSettings();
xrs.ValidationEventHandler += new System.Xml.Schema.ValidationEventHandler(xrs_ValidationEventHandler);
xrs.Schemas.Add(null, XmlReader.Create(XSDFile));
xrs.ValidationType = ValidationType.Schema;
XmlReader reader = XmlReader.Create(xmlFile, xrs);
while (reader.Read())
{}
if (hatalar.ToString() == "")
Response.Write("Hata yok");
else
Response.Write(hatalar.ToString());
}
void xrs_ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs e)
{
if (e.Severity == System.Xml.Schema.XmlSeverityType.Error)
hatalar.Append(e.Message+"<br><br>");
}
}</pre>
<p>Örneğimizi çalıştırdığımızda aşağıdaki ekran görüntüsünde yer alan hata mesajlarını elde ederiz.</p>
<p><img src="/makale/images/mk173_3.gif" alt="" width="596" height="335" border="0" /></p>
<p>Dikkat ederseniz XSD şemasında belirtilen kurallara uymayan durumlar için çeşitli hata mesajları üretilmiş ve ekrana yazılmıştır. Kodumuzdaki kilit nokta <strong> XmlReaderSettings</strong> isimli tipin XmlReader tipi ile entegrasyonudur. XmlReaderSettings sınıfına ait tek olay(event) olan <strong> ValidationEventHandler</strong>, doğrulaması yapılan Xml dökümanı içerisinde meydana gelen hatalar (errors) yada uyarılar(Warnings) sonucunda otomatik olarak tetiklenmektedir. Xml verisini kontol etmek için kullanılacak XSD şemaları, XmlReaderSettings sınıfına <strong>Schemas</strong> özelliği yardımıyla yüklenir.</p>
<p>Schemas özelliği .Net 2.0 ile gelen yeni tiplerden birisi olan <strong>XmlSchemaSet</strong> tipinden nesne örnekleri ile de çalışabilmektedir. Burada önemli olan noktalardan birisi Schemas özelliğinin aslında bir koleksiyon sunması ve Add metodu nedeni ile XmlReaderSettings için birden fazla şema bilgisinin bir arada tutulabilmesidir. Öyleki farklı xml isim alanlarına ait farklı sayıda şema bilgisini XmlReaderSettings tipleri içerisinde barındırabiliriz. XmlReaderSettings sınıfına ait bir diğer önemli üye ise <strong>ValidationType</strong> özelliğidir. Bu özelliği atadığımız değer ile (<strong>ValidationType.Schema</strong>), XSD şema tipine göre doğrulama yapacağımızı belirtmiş oluruz. Kodun ilerleyen kısımlarındaki adımlarımızda ise XmlReader sınıfımıza ait nesnemizi <strong>Create</strong> isimli statik metod ile oluşturmaktayız.</p>
<p>Örnek kodumuzda XmlReader sınıfına ait nesne örneği ile okuma yapmak için gerekli reader isimli nesneyi oluştururken static Create metodunun ilk parametresi olarak Xml dökümanımızı, ikinci parametresi olarakta doğrulama işlemleri ile ilgili bilgileri içeren XmlReaderSettings nesne örneğimizi belirtmekteyiz. Bu işlemlerin ardından tek yapılması gereken XmlReader nesne örneğinin taşıdığı içeriği ileri yönlü okumaktır. Bu amaçla kullandığımız while döngüsü ile Xml içeriğinde ileri yönlü boş bir öteleme gerçekleştirirken, XSD dosyamızın içerdiği şemada belirtilen kurallara uymayan her noktada, <strong>ValidationEventHandler</strong> olayı tetiklenir. Bizde bu olaya ilişkin metodumuz içerisinde doğrulama sonucu ortaya çıkan hataları, <strong>ValidationEventArgs</strong> tipi ile ele alabiliriz. Örnek olarak incelediğimiz Xml dökümanımızı aşağıdaki gibi düzenlersek (yani şema hatalarını ortadan kaldırırsak) uygulamamız doğrulamayı başarılı bir şekilde geçecektir.</p>
<pre class="brush:xml;auto-links:false;toolbar:false" contenteditable="false"><?xml version="1.0" encoding="utf-8"?>
<Dukkanim>
<Kitap ID="1000">
<Adi>Her Yönüyle C#</Adi>
<Fiyat>50</Fiyat>
<StokDurumu>40</StokDurumu>
<Yazarlar>
<Yazar>Sefer Algan</Yazar>
</Yazarlar>
<BasimTarihi>2003-10-11T12:00:00</BasimTarihi>
<Aciklama>C# ile ilgili yazılmış en iyi Türkçe kaynaklardan birisidir. </Aciklama>
</Kitap>
<Kitap ID="1001">
<Adi>Kahraman Asker</Adi>
<Fiyat>30</Fiyat>
<StokDurumu>1000</StokDurumu>
<Yazarlar>
<Yazar>Anonim</Yazar>
</Yazarlar>
<BasimTarihi>2004-10-11T12:00:00</BasimTarihi>
<Aciklama>C# ile ilgili yazılmış en iyi Türkçe kaynaklardan birisidir. </Aciklama>
</Kitap>
</Dukkanim></pre>
<p>XSD ile doğrulama işlemleri özellikle Xml verisi üzerinde XmlDocument tipi ile çalışırken daha büyük önem taşır. XmlDocument sınıfı bildiğiniz gibi bir Xml içeriğini bellekte <strong>DOM (Document Object Model)</strong> sistemine göre referans eder. Buda ilgili döküman üzerinde yükleme zamanında bir doğrulama işleminin yapılmasını gerektirir. Eğer bir Xml verisini, XmlDocument sınıfına ait nesneler yardımıyla ele alıyorsak, döküman içerisine yapılacak müdahalelerinde belirleyeceğimiz şema kuralları çerçevesinde olmasını garanti etmek isteyebiliriz. Durumu daha iyi analiz etmek için aşağıdaki kod parçasını ele alalım.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">string xmlFile = Server.MapPath("Dukkan.xml");
string XSDFile =Server.MapPath( "Dukkan.XSD");
hatalar = new StringBuilder();
XmlDocument doc = new XmlDocument();
doc.Load(xmlFile);
XmlElement currElement =(XmlElement)doc.DocumentElement.SelectSingleNode("//Dukkanim/Kitap[@ID='1000']");
XmlNode newNode = doc.CreateNode(XmlNodeType.Element, "SayfaSayisi", null);
newNode.InnerText = "600";
currElement.AppendChild(newNode);
doc.Save(xmlFile);</pre>
<p>Örnek kodumuzda, XmlDocument sınıfına ait doc isimli nesne örneğimizi Dukkan.xml dosyasına ait xml içeriği ile yükledikten sonra ID niteliğinin değeri 1000 olan node (boğum) kısmını elde ediyoruz. Sonrasında ise döküman üzerinde yeni bir eleman (element) oluşturuyoruz. Amacımız oluşturduğumuz yeni elemanı (element) 1000 ID numaralı Kitap boğumu altına eklemek. Bunun için SayfaSayisi isimli bu yeni xml elemanına bir değer atayıp chile node olarak dökümandaki ilgili boğumun altına ekliyoruz.</p>
<p>Bu aslında XSD şemasında <strong>tanımlanmamış</strong> bir eleman. Dolayısıylada eklenmemesi gereken bir eleman. Ancak XSD doğrulamasını hesaba katmadığımızdan bu yeni eleman Xml içeriğine gayet güzel bir şekilde eklenecektir. Öyleki örneğimizi çalıştırdığımızda Xml dökümanımızın içeriğinin aşağıdaki gibi değiştiğini görürüz. Her nekadar Vs.Net 2005 IDE' si bizi bu yeni eleman konusunda uyarsada, sonuç olarak değişiklik kod tarafından fiziki dosyaya aktarılmıştır.</p>
<p><img src="/makale/images/mk173_4.gif" alt="" width="544" height="478" border="0" /></p>
<p>O halde gelin XSD doğrulamasını işin içerisine katıp bu değişikliklerin yapılmasını engelleyelim. Bunun için yine XmlReaderSettings ve XmlReader sınıflarından yararlanacağız. Ancak bu kez XmlDocument içerisinde doğrulama işlemini gerçekleştirmek için,başka bir deyişe bellekteki Xml verisi üzerinde doğrulama yapabilmek için, <strong>XmlNodeReader</strong> isimli sınıftan faydalanacağız. Bu nedenle uygulama kodumuzu aşağıdaki gibi değiştirelim.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
StringBuilder hatalar;
protected void Page_Load(object sender, EventArgs e)
{
string xmlFile = Server.MapPath("Dukkan.xml");
string XSDFile =Server.MapPath( "Dukkan.XSD");
hatalar = new StringBuilder();
XmlDocument doc = new XmlDocument();
doc.Load(xmlFile);
XmlElement currElement =(XmlElement)doc.DocumentElement.SelectSingleNode("//Dukkanim/Kitap[@ID='1000']");
XmlNode newNode = doc.CreateNode(XmlNodeType.Element, "SayfaSayisi", null);
newNode.InnerText = "600";
currElement.AppendChild(newNode);
XmlNodeReader nodeReader = new XmlNodeReader(doc);
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.ValidationEventHandler+=new System.Xml.Schema.ValidationEventHandler(readerSettings_ValidationEventHandler);
readerSettings.ValidationType= ValidationType.Schema;
readerSettings.Schemas.Add(null,XmlReader.Create(XSDFile));
XmlReader reader = XmlReader.Create(nodeReader, readerSettings);
while (reader.Read())
{}
if (hatalar.ToString() == "")
doc.Save(xmlFile);
else
Response.Write(hatalar.ToString()+"<b>Hatası Nedeniyle Xml Dökümanının yeni içeriği kayıt edilememiştir.</b>");
}
void readerSettings_ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs e)
{
if (e.Severity == System.Xml.Schema.XmlSeverityType.Error)
hatalar.Append(e.Message + "<br><br>");
}
}</pre>
<p><img src="/makale/images/mk173_5.gif" alt="" width="469" height="110" border="0" /></p>
<p>Dilerseniz uygulama kodumuzda neler yaptığımıza kısaca bakalım. Bu sefer XmlDocument sınıfına ait doc isimli nesne örneğinin işaret ettiği bellek görüntüsünü, ilgili XSD şeması ile kontrol edebilmek amacıyla <strong>XmlNodeReader</strong> sınıfından yardım alıyoruz. Bu nedenle XmlNodeReader sınıfımıza ait nodeReader isimli nesne örneğimizi doc parametresini vererek oluşturuyoruz. Her zamanki gibi, XSD şema dosyası (Dukkan.XSD) için gerekli ayarların taşınacağı <strong> XmlReaderSettings</strong> sınıfına ait nesne örneğimizi oluşturmaktayız. Burada dikkat edilmesi gereken noktalar; doğrulama tipi (<strong>ValidationType</strong>)seçimi, doğrulama sırasında hatalar veya uyarılar sonrası tetiklenecek olayın ve metodunun hazırlanması (<strong>ValidationEventHandler</strong>) ve XSD şema dosyasının Schemas koleksiyonuna yüklenişi (<strong>Schemas.Add</strong>).</p>
<p>XSD dökümanımız ile doc isimli nesnemizin bellekte işaret ettiği Xml içeriğini çarpıştırmak dolayısıyla şema denetimi altına doğrulama kontrollerini yapmak içinse, yine XmlReader sınıfı nesne örneğinden yararlanıyoruz. Ancak bu sefer ilk parametremiz, XmlNodeReader sınıfımıza ait nodeReader isimli nesne örneğimizdir. While döngüsü ile yaptığımız boş öteleme hareketi sırasında da oluşan hata mesajlarını topluyor ve hiçbir hata yok ise Xml dökümanımızı son haliyle kaydediyoruz (<strong>doc.Save</strong>). Aslında döngü içerisinde ilerlerken, XmlReader.Create metodunda belirtiğimiz kuralları uyguluyoruz. Yani XmlNodeReader' ın taşıdığı içerik üzerinde ilerlerken XSD yi taşıyan XmlReaderSettings' teki kurallara göre doğrulama kontrolleri gerçekleştiriyoruz. Böylece geldik bir makalemizin daha sonuna. Bu makalemizde kısaca XSD şemalarını, Xml dökümanları ile çarpıştırarak yapılan doğrulama işlemlerinde .Net yönetimli tiplerinin (managed code) nasıl kullanılabileceğini incelemeye çalıştık. Bir sonraki makalemizde görüşünceye dek hepinize mutlu günler dilerim.</p>
<p><a href="https://buraksenyurt.com/makale/images/XmlValidations.rar">Örnek Uygulama İçin Tıklayın</a></p>2006-09-01T09:00:00+00:00xmlxsdbsenyurtXml içeriğini kullandığımız pek çok platformda, verinin belirli kurallara göre yazılmış olmasını istediğimiz durumlar söz konusu olabilir. Bu durum özellikle, farklı platformlar arasında taşınacak Xml tabanlı verilerin aynı kurallar dizisine uygun olacak şekilde kullanılması istendiği durumlarda karşımıza çıkmaktadır...https://buraksenyurt.com/pingback.axdhttps://buraksenyurt.com/post.aspx?id=80b43a7f-817c-472e-95b7-c4db037b007d1https://buraksenyurt.com/trackback.axd?id=80b43a7f-817c-472e-95b7-c4db037b007dhttps://buraksenyurt.com/post/XML-Verilerini-XSD-ile-Yonetimli-Kod-Uzerinden-Dogrulamak-bsenyurt-com-dan#commenthttps://buraksenyurt.com/syndication.axd?post=80b43a7f-817c-472e-95b7-c4db037b007dhttps://buraksenyurt.com/post/XPath-ve-Net-bsenyurt-com-danXPath ve .Net2006-03-04T06:00:00+00:00bsenyurt<p>Değerli Okurlarım Merhabalar,</p>
<p>XPath, XML dökümanları üzerinde basit tipte sorgulamalar yapmamıza izin veren bir dildir. Yapısı gereği kullanıldığı pek çok alan vardır. Örneğin XQuery içinde yada bir XSLT dökümanında bu dilin izlerine rahatlıkla rastlayabilirsiniz. Tam olarak yaptığı işin, XML dökümanı içerisinde lokasyon aramak ve bulmak olduğunu söyleyebiliriz. XPath, herhangibir Xml verisi üzerinde arama ve konumlandırma işlemini gerçekleştirmek için Document Object Model' i kullanılır. Yani, xml verisinin bellekteki hiyerarşik ağaç yapısını ele alır. Bunun içinde Xml verisinin yapısal (structural) metadata bilgisine bakar. XPath başlı başına bir dildir ve bu konu ile ilgili yazılmış kitaplar vardır. <em>( Size eski olmasına rağmen Sams' ın <a href="http://www.amazon.com/gp/product/0672324113/sr=8-3/qid=1141335716/ref=pd_bbs_3/102-6694554-3383307?_encoding=UTF8"> XPath Kick Start : Navigating XML with XPath 1.0 and 2.0</a> kitabını tavsiye edebilirim.) </em></p>
<p>Biz bu makalemizde çok fazla detaya inmeyecek ve XPath' i .Net üzerinde nasıl kullanabileceğimizi basit olarak incelemeye çalışacağız. Konuyu iyi anlayabilmek amacıylada XPath ile oluşturulmuş çeşitli tipteki sorguları örnek bir xml dökümanı üzerinde kullanacağız. Örneğin elimizde Kitaplara ait yazar, isim, fiyat gibi bilgileri tutan bir Xml dökümanı olduğunu düşünelim. Aşağıda bu amaçla kullanabileceğimiz Kitaplar.xml adlı xml veri dosyasının bir parçasını görüyorsunuz. (Xml dosyasını ve örnek kodları buradan <a href="https://buraksenyurt.com/makale/images/UsingXPath.rar"> indirebilirsiniz</a>.)</p>
<p><img src="/makale/images/mk150_1.gif" alt="" width="361" height="426" border="0" /></p>
<p>Bu Xml verisini göz önüne alacak olursak, XPath' in ilgili veri kümesini bellekte ağaç(tree) modeli şekline tasvir edeceğini ve buna göre yer belirleme işlemini gerçekleştireceğini söyleyebiliriz. Kitaplar.xml dosyamızın içeriğini ele aldığımızda, XPath modeli, bellek üzerinde aşağıdaki şekile benzer bir ağaç yapısını kullanacaktır. Bu hiyerarşik yapı zaten Document Object Model' in bir uyarlamasıdır.</p>
<p><img src="/makale/images/mk150_2.gif" alt="" width="565" height="344" border="0" /></p>
<p>Dikkat ederseniz Root element üzerinden xml verisi içerisinde tüm alt elementler bu elementlerin var ise atrribute' ları ele alınmaktadır. Kitaplar.xml verisinin tamamını grafiğe sığdırmamız zor olacağından sadece bir kısmı burada gösterilmetedir. İşte XPath, herhangibir kritere göre bir node listesi, tek bir node veya değer (örneğin toplam gibi) döndürmek için bu ağaç yapısını kullanacaktır. Bu modele göre XPath dili ile aşağıdaki tabloda da belirtilen örnek sorgular oluşturabiliriz.</p>
<table id="table33" style="border-collapse: collapse; width: 100%;" border="1" cellpadding="5" bgcolor="#ffffff">
<tbody>
<tr>
<td style="width: 251px;" width="251"><strong> XPath Sorgusu</strong></td>
<td style="width: 251px;"><strong> Anlamı</strong></td>
</tr>
<tr>
<td width="251">Kitaplar/Kitap</td>
<td>Kitaplar içerisindeki her bir Kitap elementini, alt elemenetleri ile birlikte elde etmemizi sağlar.</td>
</tr>
<tr>
<td width="251">Kitaplar/Kitap/@ID</td>
<td>Kitaplar içerisindeki her bir Kitap elementinin içerdiği ID attribute' larının tamamını geri döndürür.</td>
</tr>
<tr>
<td width="251">Kitaplar/Kitap[@ID=1000]</td>
<td>Kitaplar içersinde Kitap element' lerinden, ID attribute' unun değeri 1000 olan elementi (elementleri) elde etmemizi sağlar.</td>
</tr>
<tr>
<td width="251">Kitaplar/Kitap[Fiyat<=50]</td>
<td>Kitaplar içerisinde Kitap element' lerinden Fiyat element' inin değeri 50 veya daha az olanları elde etmemizi sağlar.</td>
</tr>
<tr>
<td width="251">Kitaplar/Kitap[Fiyat>50 and Fiyat<80]</td>
<td>Kitaplar içerisinde, Kitap elementler' inden Fiyat elementinin değeri 50 ile 80 arasında olanları elde etmemizi sağlar.</td>
</tr>
<tr>
<td width="251"><strong>count</strong>(/Kitaplar/Kitap)</td>
<td>Toplam Kitap sayısını verir. Bu tekil bir sonuç değeri döndürür. Üstteki sorgularda olduğu gibi bir node listesi döndürmez.</td>
</tr>
<tr>
<td width="251"><strong>sum</strong>(/Kitaplar/Kitap/Fiyat)</td>
<td>Kitapların fiyatlarının toplamını geriye döndürür. Yani Kitap node' ları içerisindeki Fiyat node' larının value özelliklerinin değerlerinin toplamını verir.</td>
</tr>
<tr>
<td width="251"><strong>sum</strong>(/Kitaplar/Kitap/Fiyat[.>70])</td>
<td>Fiyat element' inin değeri 70' den yüksek olan Kitap element' lerindeki Fiyat element' lerinin toplamını verir.</td>
</tr>
<tr>
<td width="251"><strong>count</strong>(/Kitaplar/Kitap/Fiyat[.>70])</td>
<td>Fiyat element' inin değeri 70' den yüksek olan Kitap element' lerinin sayısını verir.</td>
</tr>
</tbody>
</table>
<p><br />Buradaki sorgularda kısaltmalar(abbreviation) kullanılmıştır.(/ veya . gibi) Bunun birde kısaltma kullanılmayan(unabbreviation) şekli vardır. Genellikle kıslatmaların yer aldığı kullanım şekli daha yaygındır ve esnektir.</p>
<p>Gelelim yukarıdakine benzer XPath ifadelerini .Net üzerinde nasıl kullanacağımıza. Framework Class Library aslında tamamıyla XPath mimarisini kullanmaya yarayan tipleri barındıran System.Xml.XPath isim alanına sahiptir. Buradaki temel sınıflar yardımıyla XML dökümanları üzerinde XPath ile arama ve yer belirleme işlemlerini gerçekleştirebiliriz. Bununla birlikte bir XmlDocument nesnesinin <strong>SelectNodes</strong> veya <strong>SelectSingleNode</strong> gibi metodlarında parametre olarak XPath ifadelerini kullanabiliriz. Hangisini tercih edeceğimiz, Xml dökümanı üzerinde ne gibi işlemler yapmak istediğimize bağlıdır. Eğer Xml dökümanında belirli bir lokasyona erişip elde ettiğimiz node listelerinde değişiklikler yapmak istiyorsak XmlDocument sınıfının SelectNodes veya SelectSingleNode metodlarını tercih edebiliriz. Bununla birlikte sadece arama ve arama sonuçlarını gösterme amaçlı uygulamalarda, XPath isim alanında yer alan <strong>XPathDocument</strong> gibi sınıfları kullanmak performans ve hız açısından daha efektif sonuçlar üretecektir. Nitekim XPathDocument, XPathNavigator ve XPathNodeIterator gibi sınıflar XmlDocument sınfına göre daha performanslıdır.</p>
<p>Aşağıdaki örnek Console uygulamasında çok basit olarak XPathDocument sınıfından yararlanılarak fiyatı 50 ile 80 arasında olan kitaplara ilişkin bilgiler xml verisi içerisinde bulunarak ekrana yazdırılmaktadır. Ayrıca, fiyatı 70' den büyük olan kitapların sayısıda ekrana farklı bir teknik ile (Evaluate) yazdırılmaktadır.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">using System;
using System.Xml;
using System.Xml.XPath;
namespace UsingXPathNavigator
{
class Class1
{
static void UsingXPath()
{
XPathDocument doc = new XPathDocument("..\\..\\Kitaplar.xml");
XPathNavigator navigator = doc.CreateNavigator();
XPathNodeIterator nodes = navigator.Select("Kitaplar/Kitap[Fiyat>50 and Fiyat<80]");
while (nodes.MoveNext())
{
Console.WriteLine(nodes.Current.ToString());
}
Console.WriteLine("Toplam Kitap Sayisi (Fiyat>70) "+navigator.Evaluate("count(/Kitaplar/Kitap/Fiyat[.>70])").ToString());
}
static void Main(string[] args)
{
UsingXPath();
}
}
}</pre>
<p>Programı çalıştırdığımızda aşağıdakine benzer bir ekran görüntüsü elde ederiz.</p>
<p><img src="/makale/images/mk150_3.gif" alt="" width="638" height="112" border="0" /></p>
<p>Dilerseniz kısaca kodlarımızı inceleyelim ve ne yaptığımızı daha iyi anlamaya çalışalım. XPathDocument sınıfı, herhangibir Xml dökümanını XPath dilini kullanarak sorgulayabilmemizi sağlayan çeşitli fonksiyonelliklere ve özelliklere sahiptir. Aslında XPath, Xml dökümanlarını DOM (Document Object Model)' e uygun olan bir ağaç yapısı şeklinde inceler. Dolayısıyla XPathDocument sınıfı xml verisini bu modele uygun bir bellek görüntüsünü oluşturmak amacıyla kullanılır. XPathDocument sınıfına ait bir nesne örneği ile belleğe alınan ağaç modeli üzerinde hareket edebilmek için, <strong> XPathNavigator</strong> sınıfına ait metodlar kullanılabilir. XPathNavigator, abstract bir sınıf olduğundan (yani nesne örneği oluşturulamayan bir sınıf), XPathDocument sınıfının <strong>CreateNavigator</strong> metodu yardımıyla oluşturulur.</p>
<p>XPathNavigator sınıfı iki önemli metod sunar. Bunlar <strong>Select</strong> ve <strong>Evaluate</strong> metodlarıdır. Select metodu çoğunlukla geriye birden fazla sayıda sonuç döneceği zaman kullanılır. Örneğimizde olduğu gibi. Select metodu aslında geriye <strong> XPathNodeIterator</strong> tipinden bir nesne örneği döndürmektedir. Bu sınıf basit olarak, Select metodu sonucu elde edilen veri seti üzerinde, ileri yönlü hareket etmemizi sağlar. Biz bu iterasyon ile Kitap node' larının tüm içeriğini ekrana yazdırıyoruz. Ancak gördüğünüz gibi ekran çıktısı çokta mükemmel değil. Aşağıdaki kod parçasıda, Kitap node' larının alt node' larındada ileri yönlü hareket ediyor ve içeriğin daha okunabilir olmasını sağlıyoruz. Öyleki XML dökümanımızda Kitap node' larının alt node' larından olan Yazarlar node' ununda alt node' ları var. Bu yüzden iç içe 3 while iterasyonu yazmamız gerekiyor.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">static void UsingXPathSecond()
{
XPathDocument doc = new XPathDocument("..\\..\\Kitaplar.xml");
XPathNavigator navigator = doc.CreateNavigator();
XPathNodeIterator nodes = navigator.Select("Kitaplar/Kitap[Fiyat>50 and Fiyat<80]");
// İlk olarak sorgu sonucu elde edile fiyatı 50 ile 80 arasındaki Kitap node' larında hareket ediyoruz.
while (nodes.MoveNext())
{
// Her bir Kitap elementinin alt node' larını alıyoruz ve bu node' lar içerisinde ileri yönlü hareket ediyoruz.
XPathNodeIterator childNodes=nodes.Current.SelectChildren(XPathNodeType.Element);
while(childNodes.MoveNext())
{
// Eğer o anki alt node'un adı Yazarlar ise bu kez güncel Kitap node' unun altındaki Yazarlar node' unun alt node' ları içerisinde ileri doğru hareket ediyoruz. Eğer güncel alt node Yazarlar node' u değilse o node' un adını ve değerini yazdırıyoruz.
if(childNodes.Current.Name=="Yazarlar")
{
XPathNodeIterator yazarlarNodes=childNodes.Current.SelectChildren(XPathNodeType.Element);
Console.Write("Yazar(lar) : ");
while(yazarlarNodes.MoveNext())
{
Console.Write(yazarlarNodes.Current.Value+", ");
}
Console.WriteLine();
}
else
{
Console.WriteLine(childNodes.Current.Name+":"+childNodes.Current.Value);
}
}
Console.WriteLine();
}
Console.WriteLine("Toplam Kitap Sayisi (Fiyat>70) "+navigator.Evaluate("count(/Kitaplar/Kitap/Fiyat[.>70])").ToString());
}</pre>
<p><img src="/makale/images/mk150_4.gif" alt="" width="641" height="272" border="0" /></p>
<p>XPathNavigator sınıfımızın yukarıdaki örneklerde kullandığımız diğer önemli fonksiyonelliğinin Evaluate metodu ile sağlandığını söylemiştik. Bu metod geriye object tipinden bir değer döndürmektedir. Bu yüzden örneğimizde olduğu gibi <strong>count</strong> ile hesaplanan tek bir değeri almak için birebirdir. Evaluate metodunu, Command sınıfının ExecuteScalar metoduna benzetebilirisiniz. Her ikiside bir veri seti üzerinden geriye tek bir değer döndürmek amacıyla kullanılır.</p>
<p>XPath dilini kullanabileceğimiz tek tip XPatDocument sınıfı ve bununla ilişkili diğer sınıflar değildir. XPath dili ile yazılan sorguları <strong>XmlDocument</strong> sınıfına ait herhangibir nesne örneği içinde de kullanabiliriz. XmlDocument sınıfının <strong> SelectNodes</strong> ve <strong>SelectSingleNode</strong> isimli metodları parametre olarak XPath tipinden ifadelerde almaktadır. Örneğin aşağıdaki kod parçasında XmlDocument sınıfından nesne örneğimizin bellekte tuttuğu xml verisi içerisinde Bill Evjen isimli yazara ait Kitap node' larının listesi elde edilmektedir. SelectNodes metodu ile bulunan node' ları aldıktan sonra bunların sayısına bakaraktan üst node' lara (parent node) nasıl çıktığımıza dikkat edin.</p>
<pre class="brush:csharp;auto-links:false;toolbar:false" contenteditable="false">static void UsingXmlDoc()
{
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("..\\..\\Kitaplar.xml");
XmlNodeList resultNodes = xmldoc.SelectNodes("/Kitaplar/Kitap/Yazarlar[Yazar='Bill Evjen']");
XmlNode currNode;
XmlNode parentNode;
if(resultNodes.Count==1)
{
currNode=resultNodes[0];
parentNode=currNode.ParentNode;
Console.WriteLine(parentNode.InnerText);
}
else
{
foreach(XmlNode aNode in resultNodes)
{
parentNode=aNode.ParentNode;
Console.WriteLine(parentNode.InnerText);
}
}
}
static void Main(string[] args)
{
UsingXmlDoc();
}</pre>
<p><img src="/makale/images/mk150_5.gif" alt="" width="639" height="95" border="0" /></p>
<p>Böylece geldik bir makalemizin daha sonuna. Bu makalemizde XPath dili ile geliştirdiğimiz sorguları .Net sınıfları ile nasıl kullanabileceğimizi inceledik. Özetlemek gerekirse, XPath modelinin sunduğu imkanları kullanabileceğimiz yerler XPathDocument sınıfı ve XmlDocument sınıflarıdır. Her iki sınıf ile XPath ifadelerini etkin bir şekilde kullanabiliyoruz. Bunlara ek olaraktan ileridede göreceğimiz gibi XPath ifadelerini XQuery veya XSLT içerisinde de aktif olarak kullanmaktayız. Bu modelleri daha sonraki yazılarımızda incelemeye çalışacağız. Bir sonraki makalemizde görüşünceye dek hepinize mutlu günler dilerim.</p>2006-03-04T06:00:00+00:00xmlxpathbsenyurtXPath, XML dökümanları üzerinde basit tipte sorgulamalar yapmamıza izin veren bir dildir. Yapısı gereği kullanıldığı pek çok alan vardır. Örneğin XQuery içinde yada bir XSLT dökümanında bu dilin izlerine rahatlıkla rastlayabilirsiniz. Tam olarak yaptığı işin, XML dökümanı içerisinde lokasyon aramak ve bulmak olduğunu söyleyebiliriz. XPath, herhangibir Xml verisi üzerinde arama ve konumlandırma işlemini gerçekleştirmek için Document Object Model' i kullanılır. Yani, xml verisinin bellekteki hiyerarşik ağaç yapısını ele alır. Bunun içinde Xml verisinin yapısal (structural) metadata bilgisine bakar. XPath başlı başına bir dildir ve bu konu ile ilgili yazılmış kitaplar vardır. ( Size eski olmasına rağmen Sams' ın XPath Kick Start : Navigating XML with XPath 1.0 and 2.0 kitabını tavsiye edebilirim.)https://buraksenyurt.com/pingback.axdhttps://buraksenyurt.com/post.aspx?id=d0357e66-2afb-496f-93a6-2b2bcd31300d1https://buraksenyurt.com/trackback.axd?id=d0357e66-2afb-496f-93a6-2b2bcd31300dhttps://buraksenyurt.com/post/XPath-ve-Net-bsenyurt-com-dan#commenthttps://buraksenyurt.com/syndication.axd?post=d0357e66-2afb-496f-93a6-2b2bcd31300d