Linq ve XML
Bu yazıda linq kullanarak XML'i sorgulama örnekleri var. İkinci yazıda Linq kullanarak XML oluşturma, üçüncü yazı sorgulanan XML'i başka bir veri yapısına dönüştürme hakkında.
Linq to XML System.Linq.XML namespece'i içindeki sınıflardan oluşuyor. Şu sınıflardan oluşuyor.
XML Yükleme
XML'i yüklemek için XDocument veya XElement sınıfları kullanılabilir.İkisi arasında fark var.
Load Metodu
Load metodu string, stream, textreader, xmlreader gibi bir sürü sınıfı kullanabiliyor.
Parse Metodu
Parse metodu sadece string'i kullanabiliyor. Load varken neden Parse kullanılır bilmiyorum.
Örnek
XDocument sınıfı
Sorgulamalarda aranılan düğüm bulunduktan sonra genellikle ya node.Value veya node.Attribute ile düğümün verisine erişilir.
Descendants metodu ile sorgulama
Descendants metodu IEnumerable döndüğü için IEnumerable ile kullanılan tüm metodları kullanabiliriz.
Tüm Düğümleri Dolaşma
Örnekte tüm düğümler dolaşılarak düğümlerin içerdikleri değerler alınıyor.
Elimizde aşağıki XML olsun
<Channel Id="1">
<Destination NameRef="MyRef"/>
<Channel>
NameRef'e göre arama yapıp Id attribute değerini almak için
XDocument doc = //...
XNamespace ns = document.Root.Name.Namespace;
var el = document.Descendants (ns + "Destination").
Where (x=>(string)z.Attribute ("NameRef") == "MyNameRef").First ();
string result = el.Parent.Attribute ("Id");
Namespace İçinde Arama yapma
XMLdokümanları genellikle bir namespace içindedirler. namespace url formatındadır. Aşağıda namespace ile başlayan xml görülebilir.
Descendants ile aynı. Aramayı başlatan düğüm de arama kriterini sağlıyorsa sonuca dahil edilir.
Element metodu
Elimizde şöyle bir XML olsun.
Elements metodu ile sorgulama
Elements ile Descendants arasındaki fark var. Descendants verilen yoldan itibaren tüm alt düğümleri dolaşır. Elements ise sadece ilk alt düğümleri dolaşır. Örnek'te XDocument türünden bir değişken olan doc'tan summary/accounts bilgileri çekiliyor.
XInclude Nedir
XInclude ile bir xml bir başka xml belgesini içerebilir. Xinclude uzun süredir var olmasına rağmen pek kullanılmaz. Microsoft'un XML okuyucuları da xinclude tag'ini desteklemiyor. Bu yüzden aşağıda kendim bir şeyler yazdım. Verilen düğüm diğer dosya ile yer değiştiriliyor. Diğer dosyanın path ile aynı dizinde olduğunu farz ettim.
Bu yazıda linq kullanarak XML'i sorgulama örnekleri var. İkinci yazıda Linq kullanarak XML oluşturma, üçüncü yazı sorgulanan XML'i başka bir veri yapısına dönüştürme hakkında.
Linq to XML System.Linq.XML namespece'i içindeki sınıflardan oluşuyor. Şu sınıflardan oluşuyor.
XML Yükleme
XML'i yüklemek için XDocument veya XElement sınıfları kullanılabilir.İkisi arasında fark var.
Load Metodu
Load metodu string, stream, textreader, xmlreader gibi bir sürü sınıfı kullanabiliyor.
Parse Metodu
Parse metodu sadece string'i kullanabiliyor. Load varken neden Parse kullanılır bilmiyorum.
Örnek
XElement config = XElement.Parse (xml);
veyavar doc = XDocument.Parse(xml);
XDocument sınıfı
Sorgulamalarda aranılan düğüm bulunduktan sonra genellikle ya node.Value veya node.Attribute ile düğümün verisine erişilir.
Descendants metodu ile sorgulama
Descendants metodu IEnumerable döndüğü için IEnumerable ile kullanılan tüm metodları kullanabiliriz.
Tüm Düğümleri Dolaşma
Örnekte tüm düğümler dolaşılarak düğümlerin içerdikleri değerler alınıyor.
var doc = XDocument.Parse(xml);
string[] values = doc.Root.Descendants().Select(x => x.Value).ToArray();
Attribute İle Arama YapmaElimizde aşağıki XML olsun
<Channel Id="1">
<Destination NameRef="MyRef"/>
<Channel>
NameRef'e göre arama yapıp Id attribute değerini almak için
XDocument doc = //...
XNamespace ns = document.Root.Name.Namespace;
var el = document.Descendants (ns + "Destination").
Where (x=>(string)z.Attribute ("NameRef") == "MyNameRef").First ();
string result = el.Parent.Attribute ("Id");
Namespace İçinde Arama yapma
XMLdokümanları genellikle bir namespace içindedirler. namespace url formatındadır. Aşağıda namespace ile başlayan xml görülebilir.
<?xml version="1.0" encoding="us-ascii"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
...
</WLANProfile>
Eğer Namespace aranılan tag'e dahil edilmezse, arama default namespace içinde yapıldığı için sonuç boş döner. Bu yüzden namespace'i de aramaya dahil etmek gerekir.XNamespace ns = document.Root.Name.Namespace;
XElement name = xdoc.Root.Element(ns + "name");
Tüm Düğümleri Dolaşma,Namespace İçinde Attribute İle Arama Yapma Örneği
Örnekte Visual Studio proje dosyasının içini okuyoruz. Projeye dahil edilen dosyanın gerçekte diskte olup olmadığını kontrol ediyoruz.
string path = "......\myproject.vcxproj";
string directoryName = Path.GetDirectoryName (path);
XDocument doc = XDocument.Load (path);
XNamespace ns = doc.Root.Name.Namespace;
var itemGroup = doc.Descendants (ns + "ItemGroup").Skip (1). First (). Elements. Select (s => s.Attribute ("Include").Value).ToList ();
foreach (var item in itemGroup)
{
string canonicalPath = Path.Combine (directoryName, item);
canonicalPath = new Uri (canonicalPath).LocalPath;
if (File.Exists (canonicalPath) == false)
{
Console.WriteLine (canonicalPath + " does not exist!");
}
}
DescendantsAndSelf metoduÖrnekte Visual Studio proje dosyasının içini okuyoruz. Projeye dahil edilen dosyanın gerçekte diskte olup olmadığını kontrol ediyoruz.
string path = "......\myproject.vcxproj";
string directoryName = Path.GetDirectoryName (path);
XDocument doc = XDocument.Load (path);
XNamespace ns = doc.Root.Name.Namespace;
var itemGroup = doc.Descendants (ns + "ItemGroup").Skip (1). First (). Elements. Select (s => s.Attribute ("Include").Value).ToList ();
foreach (var item in itemGroup)
{
string canonicalPath = Path.Combine (directoryName, item);
canonicalPath = new Uri (canonicalPath).LocalPath;
if (File.Exists (canonicalPath) == false)
{
Console.WriteLine (canonicalPath + " does not exist!");
}
}
Descendants ile aynı. Aramayı başlatan düğüm de arama kriterini sağlıyorsa sonuca dahil edilir.
Element metodu
Elimizde şöyle bir XML olsun.
<?xml version="1.0" encoding="utf-8"?>
<Server>
JSODYAPP01T
</Server>
Server tag'inin değerini şöyle alırızvar serverName = XDocument.Load(response.GetResponseStream()).Element("Server").Value;
Elements metodu ile sorgulama
Elements ile Descendants arasındaki fark var. Descendants verilen yoldan itibaren tüm alt düğümleri dolaşır. Elements ise sadece ilk alt düğümleri dolaşır. Örnek'te XDocument türünden bir değişken olan doc'tan summary/accounts bilgileri çekiliyor.
var accounts = doc.Root.Elements("summary").Elements("account");
XInclude Nedir
XInclude ile bir xml bir başka xml belgesini içerebilir. Xinclude uzun süredir var olmasına rağmen pek kullanılmaz. Microsoft'un XML okuyucuları da xinclude tag'ini desteklemiyor. Bu yüzden aşağıda kendim bir şeyler yazdım. Verilen düğüm diğer dosya ile yer değiştiriliyor. Diğer dosyanın path ile aynı dizinde olduğunu farz ettim.
public static class XIncludeExtention
{
// Be aware of the different 2001 and 2003 standard.
static XNamespace IncludeNamespace = "http://www.w3.org/2003/XInclude";
static XName IncludeElementName = IncludeNamespace + "include";
public const string IncludeLocationAttributeName = "href";
public static void ReplaceXIncludes(this XDocument xDoc,string path)
{
ReplaceXIncludes(xDoc.Root,path);
}
static void ReplaceXIncludes(this XElement xmlElement, string path)
{
var r=xmlElement.Descendants(IncludeElementName).ToArray<XElement>();
foreach (var includeElement in r)
{
var doc = XDocument.Load(path);
includeElement.ReplaceWith(doc.Root);
}
}
}
Hiç yorum yok:
Yorum Gönder