11 Haziran 2015 Perşembe

XML Dosyasından Veri Okuma

Selam,
Bu yazımda bir XML dosyasındaki veriyi, veri tabanındaki ilgili tabloya ekleme işlemi yapan basit bir console application oluşturmayı anlatacağım. Ek olarak bir XML dosyasını okuyup konsola yazdırma işini de yapacağım. Kullandığım veri tabanı MsSQL, yazdığım dil C# ve uygulama türü ConsoleApplication.

Daha önce XML dosyası okuma/yazma vs ile pek işim olmamıştı. Dolayısıyla her zamanki gibi: "how to write sql to read from XML file?!..." gibi ufak bir araştırmadan sonra gerek msdn, gerek stackoverflow dan bunun yöntemini öğrenip, bulduklarımı toparladım ve istenen ihtiyacı karşıladım. Tabii ki sizleri de unutmadım, neyse lafı daha fazla uzatmadan...

Kodlar aşağıdadır, afiyet olsun.

Not: Örnek olması açısından database olarak çok rahat bulabileceğimiz Northwind database i kullandım, sokakta köşeyi dönseniz bile karşınıza çıkar. XML dosyasını kendim yazdım; Northwind içindeki Employees tablosuna veri eklediğim bir program bu. Employees tablosundan bazı sütunları sildim (Photo gibi) ve nvarchar tipindeki karakter sayısı verilen sütunları nvarchar(max) olarak değiştirdim ki veri uzunluğundan karşılaştığım ekleme hatalarını giderebilmek adına.

Küçük Bir Hatırlatma: MsSQL'de Table Design'de yaptığın bu değişikleri(sütun silme, veri tipi değiştirme..) kaydetme hatası alıyorsan ; MSSQL-> Tools sekmesini seç -> Options -> Designers seçtiğinde;  Prevent saving changes that require table re-creation daki tiki kaldırıp Ok seç. Bundan sonra tablo dizaynında istediğin değişikliği yapıp kaydedebilir; tekrardan yeni bir tablo oluşturmak zorunda kalmazsın.

 Yazdığım XML dosyasından sildiğim veri anlaşılacaktır o da bu:

Employees.xml (Proje->bin->debug içinden erişerek düzenleyebilirsin)

<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <Employees>
    <EmployeeID>10</EmployeeID>
    <LastName>john</LastName>
    <FirstName>london</FirstName>
    <Title>article</Title>
    <TitleOfCourtesy>Ms.</TitleOfCourtesy>
    <BirthDate>1944-12-08T00:00:00+02:00</BirthDate>
    <HireDate>1954-06-01T00:00:00+03:00</HireDate>
<Address> a plaza b blok c katı</Address>
    <City>508 - 20th Ave. E.
Apt. 2A</City>
    <Region>WA</Region>
    <PostalCode>98322</PostalCode>
    <Country>USA</Country>
    <HomePhone>(535) 111-9857</HomePhone>
    <Extension>66776</Extension>
    <Notes>Educatioxfgnvxfcfgcfal.</Notes>
    <ReportsTo>5</ReportsTo>
    <PhotoPath>http://google.com</PhotoPath>
  </Employees>
  
</DocumentElement>

App.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
    </configSections>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <connectionStrings>
    <add name="TestConnectionString" connectionString="Data Source=servername;Initial Catalog=northwind;User ID=sa;Password=şifre" />
    <add name="TestProject.Properties.Settings.northwindConnectionString"
      connectionString="Data Source=servername;Initial Catalog=northwind;Persist Security Info=True;User ID=sa;Password=şifre"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

Program.cs

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace TestProject //VS New Project-Console Application ProjectName
{

    class Program
    {
        private static void TableToXml()//XML dosyasının içeriğini //konsolda gösteren fonksiyon
        {
            try
            {
//Burada App.config içerisindeki connectionString i alıyorum
                string ConString = System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString;
                string CmdString = "SELECT EmployeeID, LastName, FirstName, Title, TitleOfCourtesy, BirthDate, HireDate, Address,City, Region, PostalCode, Country, HomePhone, Extension, Notes, ReportsTo, PhotoPath FROM Employees";

                SqlConnection con;
                SqlCommand cmd;
                SqlDataAdapter sda;
                DataTable dt;

//Bir DataTable oluşturarak verileri bu DataTable'a atıyorum ve DataTable'i dolduruyorum
                using (con = new SqlConnection(ConString))
                {
                    cmd = new SqlCommand(CmdString, con);

                    con.Open();
                    dt = new DataTable("Employees");
                    sda = new SqlDataAdapter(cmd);
                    sda.Fill(dt);
                    dt.WriteXml("Employees.xml");
                    con.Close();
                }

//XML dosyasını burada okuyorum

                XmlTextReader reader = new XmlTextReader("Employees.xml");
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            Console.Write("<" + reader.Name);
                            Console.WriteLine(">");
                            break;
                        case XmlNodeType.Text:
                            Console.WriteLine(reader.Value);
                            break;
                        case XmlNodeType.EndElement:
                            Console.Write("</" + reader.Name);
                            Console.WriteLine(">");
                            break;
                    }
                }

                Console.ReadLine();
            }
            catch (Exception)
            {
                throw;
            }
        }
//XML dosyasındaki veriyi veritabanındaki ilgili tabloya ekleme işlemini yapan fonksiyon
        private static void XmlToDB()
        {
            string ConString = System.Configuration.ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString;
            SqlConnection connection;
            SqlCommand command;
            SqlDataAdapter adpter = new SqlDataAdapter();
            DataSet ds = new DataSet();
            XmlReader xmlFile;
            string sql = null;

            int EmployeeID = 0;
            string LastName = null;
            string FirstName = null;
            string Title = null;
            string TitleOfCourtesy = null;
            DateTime BirthDate = DateTime.Now;
            DateTime HireDate = DateTime.Now;
            string Address = null;
            string City = null;
            string Region = null;
            string PostalCode = null;
            string Country = null;
            string HomePhone = null;
            string Extension = null;
            string Notes = null;
            byte[] Photo= {0};
            int ReportsTo = 0;
            string PhotoPath = null;

            try { 
            connection = new SqlConnection(ConString);

            xmlFile = XmlReader.Create("Employees.xml", new XmlReaderSettings());
            ds.ReadXml(xmlFile);
            int i = 0;
            connection.Open();
            for (i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
            {
                EmployeeID = Convert.ToInt32(ds.Tables[0].Rows[i].ItemArray[0]);
                LastName = ds.Tables[0].Rows[i].ItemArray[1].ToString();
                FirstName = ds.Tables[0].Rows[i].ItemArray[2].ToString();
                Title = ds.Tables[0].Rows[i].ItemArray[3].ToString();
                TitleOfCourtesy = ds.Tables[0].Rows[i].ItemArray[4].ToString();
                BirthDate = Convert.ToDateTime(ds.Tables[0].Rows[i].ItemArray[5]);
                HireDate = Convert.ToDateTime(ds.Tables[0].Rows[i].ItemArray[6]);
                Address = ds.Tables[0].Rows[i].ItemArray[7].ToString();
                City = ds.Tables[0].Rows[i].ItemArray[8].ToString();
                Region = ds.Tables[0].Rows[i].ItemArray[9].ToString();
                PostalCode = ds.Tables[0].Rows[i].ItemArray[10].ToString();
                Country = ds.Tables[0].Rows[i].ItemArray[11].ToString();
                HomePhone = ds.Tables[0].Rows[i].ItemArray[12].ToString();
                Extension = ds.Tables[0].Rows[i].ItemArray[13].ToString();
                Notes = ds.Tables[0].Rows[i].ItemArray[14].ToString();             
                ReportsTo = Convert.ToInt32(ds.Tables[0].Rows[i].ItemArray[15]); ;
                PhotoPath = ds.Tables[0].Rows[i].ItemArray[16].ToString();
                sql = "INSERT INTO Employees VALUES('" + LastName + "','" + FirstName + "','" + Title + "','" + TitleOfCourtesy + "','" + BirthDate + "','" + HireDate + "','" + Address + "','" + City + "','" + Region + "','" + PostalCode + "','" + Country + "','" + HomePhone + "','" + Extension + "','" + Notes + "'," + ReportsTo + ",'" + PhotoPath + "')";
                command = new SqlCommand(sql, connection);
                adpter.InsertCommand = command;
                adpter.InsertCommand.ExecuteNonQuery();
                Console.WriteLine("Kayıt veri tabanına eklendi.");
                Console.ReadLine();                                                                                                               
            }                                                               //string,datetime vb. tipindeki değişkenlere sql sorgusu yazarken '' vermeyi unutmuyoruz.                                                                                                                                             
            connection.Close();
            }
            catch(Exception)
            {
                Console.WriteLine("Kayıt ekleme işlemi başarısız!");
                Console.ReadLine(); 
            }                                                                                                                                                                  
        }                                                                                                                                
        static void Main(string[] args)
        {
            TableToXml();
            XmlToDB();
        }
    }
}