C# + LINQ ile XML/RSS dosyasından bilgi okuma
Bu yazımızda C# ile XML dosyalarını okuma konusunu işleyeceğiz. Hem dosyadan hem de URL den okumayı göreceğiz.
XML okuma işlemlerini farklı yollardan yapabiliriz ama bu yazıda;
using System.Xml; using System.Xml.Linq;
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- Edited by XMLSpy® --> <CATALOG> <CD> <TITLE>Empire Burlesque</TITLE> <ARTIST>Bob Dylan</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>10.90</PRICE> <YEAR>1985</YEAR> </CD> <CD> <TITLE>Hide your heart</TITLE> <ARTIST>Bonnie Tyler</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>CBS Records</COMPANY> <PRICE>9.90</PRICE> <YEAR>1988</YEAR> </CD> <CD> <TITLE>Greatest Hits</TITLE> <ARTIST>Dolly Parton</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>RCA</COMPANY> <PRICE>9.90</PRICE> <YEAR>1982</YEAR> </CD> <CD> <TITLE>Still got the blues</TITLE> <ARTIST>Gary Moore</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Virgin records</COMPANY> <PRICE>10.20</PRICE> <YEAR>1990</YEAR> </CD> <CD> <TITLE>Eros</TITLE> <ARTIST>Eros Ramazzotti</ARTIST> <COUNTRY>EU</COUNTRY> <COMPANY>BMG</COMPANY> <PRICE>9.90</PRICE> <YEAR>1997</YEAR> </CD> <CD> <TITLE>One night only</TITLE> <ARTIST>Bee Gees</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Polydor</COMPANY> <PRICE>10.90</PRICE> <YEAR>1998</YEAR> </CD> <CD> <TITLE>Sylvias Mother</TITLE> <ARTIST>Dr.Hook</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>CBS</COMPANY> <PRICE>8.10</PRICE> <YEAR>1973</YEAR> </CD> <CD> <TITLE>Maggie May</TITLE> <ARTIST>Rod Stewart</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Pickwick</COMPANY> <PRICE>8.50</PRICE> <YEAR>1990</YEAR> </CD> <CD> <TITLE>Romanza</TITLE> <ARTIST>Andrea Bocelli</ARTIST> <COUNTRY>EU</COUNTRY> <COMPANY>Polydor</COMPANY> <PRICE>10.80</PRICE> <YEAR>1996</YEAR> </CD> <CD> <TITLE>When a man loves a woman</TITLE> <ARTIST>Percy Sledge</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Atlantic</COMPANY> <PRICE>8.70</PRICE> <YEAR>1987</YEAR> </CD> <CD> <TITLE>Black angel</TITLE> <ARTIST>Savage Rose</ARTIST> <COUNTRY>EU</COUNTRY> <COMPANY>Mega</COMPANY> <PRICE>10.90</PRICE> <YEAR>1995</YEAR> </CD> <CD> <TITLE>1999 Grammy Nominees</TITLE> <ARTIST>Many</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Grammy</COMPANY> <PRICE>10.20</PRICE> <YEAR>1999</YEAR> </CD> <CD> <TITLE>For the good times</TITLE> <ARTIST>Kenny Rogers</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Mucik Master</COMPANY> <PRICE>8.70</PRICE> <YEAR>1995</YEAR> </CD> <CD> <TITLE>Big Willie style</TITLE> <ARTIST>Will Smith</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Columbia</COMPANY> <PRICE>9.90</PRICE> <YEAR>1997</YEAR> </CD> <CD> <TITLE>Tupelo Honey</TITLE> <ARTIST>Van Morrison</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Polydor</COMPANY> <PRICE>8.20</PRICE> <YEAR>1971</YEAR> </CD> <CD> <TITLE>Soulsville</TITLE> <ARTIST>Jorn Hoel</ARTIST> <COUNTRY>Norway</COUNTRY> <COMPANY>WEA</COMPANY> <PRICE>7.90</PRICE> <YEAR>1996</YEAR> </CD> <CD> <TITLE>The very best of</TITLE> <ARTIST>Cat Stevens</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Island</COMPANY> <PRICE>8.90</PRICE> <YEAR>1990</YEAR> </CD> <CD> <TITLE>Stop</TITLE> <ARTIST>Sam Brown</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>A and M</COMPANY> <PRICE>8.90</PRICE> <YEAR>1988</YEAR> </CD> <CD> <TITLE>Bridge of Spies</TITLE> <ARTIST>T'Pau</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Siren</COMPANY> <PRICE>7.90</PRICE> <YEAR>1987</YEAR> </CD> <CD> <TITLE>Private Dancer</TITLE> <ARTIST>Tina Turner</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>Capitol</COMPANY> <PRICE>8.90</PRICE> <YEAR>1983</YEAR> </CD> <CD> <TITLE>Midt om natten</TITLE> <ARTIST>Kim Larsen</ARTIST> <COUNTRY>EU</COUNTRY> <COMPANY>Medley</COMPANY> <PRICE>7.80</PRICE> <YEAR>1983</YEAR> </CD> <CD> <TITLE>Pavarotti Gala Concert</TITLE> <ARTIST>Luciano Pavarotti</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>DECCA</COMPANY> <PRICE>9.90</PRICE> <YEAR>1991</YEAR> </CD> <CD> <TITLE>The dock of the bay</TITLE> <ARTIST>Otis Redding</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>Atlantic</COMPANY> <PRICE>7.90</PRICE> <YEAR>1987</YEAR> </CD> <CD> <TITLE>Picture book</TITLE> <ARTIST>Simply Red</ARTIST> <COUNTRY>EU</COUNTRY> <COMPANY>Elektra</COMPANY> <PRICE>7.20</PRICE> <YEAR>1985</YEAR> </CD> <CD> <TITLE>Red</TITLE> <ARTIST>The Communards</ARTIST> <COUNTRY>UK</COUNTRY> <COMPANY>London</COMPANY> <PRICE>7.80</PRICE> <YEAR>1987</YEAR> </CD> <CD> <TITLE>Unchain my heart</TITLE> <ARTIST>Joe Cocker</ARTIST> <COUNTRY>USA</COUNTRY> <COMPANY>EMI</COMPANY> <PRICE>8.20</PRICE> <YEAR>1987</YEAR> </CD> </CATALOG>
XML'i sabit bir dosyadan okuma:
string dosya = Server.MapPath("~/App_Data/xmldosya.xml"); XmlTextReader reader = new XmlTextReader(dosya); XElement xel = XElement.Load(reader); gv.DataSource = from x in xel.Elements("CD") where Convert.ToInt32(x.Element("YEAR").Value) > 1990 select new { Title = x.Element("TITLE").Value, Year = x.Element("YEAR").Value }; gv.DataBind();
string dosya = Application.StartupPath + @"\Data\xmldosya.xml"; XmlTextReader reader = new XmlTextReader(dosya); XElement el = XElement.Load(reader);
gerisi aynı.. :)
Application.StartupPath(), çalıştırdığımız programın yolunu döndürür.
URL'den XML dosyasını okuma:
Şimdi de sabit bir dosyadan değil de direkt olarak URL'den xml dosyasını okuyalım.
Örnek olarak, XML dosyasını kaydettiğimiz adresi kullanalım: http://www.w3schools.com/xml/cd_catalog.xml
string url = "http://www.w3schools.com/xml/cd_catalog.xml"; XElement xel = XElement.Load(url);
<?xml version="1.0" encoding="utf-8"?> <rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"> <channel> <title>Title bilgisi</title> <link>http://www.daltinkurt.com</link> <description>daltinkurt.com</description> <item> <title>Başlık 1</title> <link>http://www.daltinkurt.com/abc.aspx</link> <description>Açıklama, açıklama, ...</description> <category>GÜNCEL</category> <pubDate>Mon, 05 Nov 2012 16:56:53 GMT</pubDate> <guid>1234566</guid> <dc:creator>daltinkurt</dc:creator> <dc:date>2012-11-05T16:56:53Z</dc:date> </item> <item> <title>Başlık 2</title> <link>http://www.daltinkurt.com/xyz.aspx</link> <description>Açıklama, açıklama, ...</description> <category>GÜNCEL</category> <pubDate>Mon, 05 Nov 2012 16:51:48 GMT</pubDate> <guid>1234567</guid> <dc:creator>daltinkurt</dc:creator> <dc:date>2012-11-05T16:51:48Z</dc:date> </item> ... </channel> </rss>
string dosya = Server.MapPath("~/App_Data/xmldosya.xml"); XmlTextReader reader = new XmlTextReader(dosya); XElement xel = XElement.Load(reader); gv.DataSource = from x in xel.Element("channel").Elements("item") select new { Baslik = x.Element("title").Value, Tarih = x.Element("dc:date").Value }; gv.DataBind();
Sonuç:
'/xml' Uygulamasında Sunucu Hatası.
':' karakteri (onaltılı değeri 0x3A), bir adın içinde bulunamaz.
Açıklama: Geçerli web isteği yürütülürken işlenmemiş özel durum oluştu. Lütfen hata ve kod içinde kaynaklandığı yer hakkında daha fazla bilgi almak için yığın izlemesini gözden geçirin.Özel Durum Ayrıntıları: System.Xml.XmlException: ':' karakteri (onaltılı değeri 0x3A), bir adın içinde bulunamaz.
Yukarıdaki hatayı aldık. dc:date tagını kodlarımız kabul etmedi. Enteresan bir hata bence, değil mi? :)
Çözümü de son derece kolay.
XML dosyamızın en üstünde
<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
şeklinde bir tanımlama satırı var. dc:date tagının başındaki dc önekini bu satırda hangi xml namespace ine ait olduğunu tanımlıyor.
O zaman, kodlarımızda ufak bir değişikliğe gidelim:
string dosya = Server.MapPath("~/App_Data/xmldosya.xml"); XmlTextReader reader = new XmlTextReader(dosya); XElement xel = XElement.Load(reader); XNamespace dc = "http://purl.org/dc/elements/1.1/"; gv.DataSource = from x in xel.Element("channel").Elements("item") select new { Baslik = x.Element("title").Value, Tarih = x.Element(dc + "date").Value }; gv.DataBind();
XNamespace ile dc öntanımının hangi namespace e denk geldiğini tanımlıyoruz ve artık dc:xxx barındıran tagları direkt değil de dc + "xxx" şeklinde kullanıyoruz. Hepsi bu.
Aynı dosya üzerinde bir de sorgulama yapalım:
string dosya = Server.MapPath("~/App_Data/xmldosya.xml"); XmlTextReader reader = new XmlTextReader(dosya); XElement xel = XElement.Load(reader); XNamespace dc = "http://purl.org/dc/elements/1.1/"; gv.DataSource = from x in xel.Element("channel").Elements("item") where x.Element(dc + "creator").Value.Equals("daltinkurt") select new { Baslik = x.Element("title").Value, Tarih = x.Element(dc + "date").Value }; gv.DataBind();
Mantığı anladınız sanırım.
Herkese bol C#'lı LINQ'li XML'li günler diliyorum. :)
#xml #linq #XmlTextReader #XElement #XNamespace #Server-MapPath #Application-StartupPath #rss