Fetching Data From XML File To SQL Database

In this article, I will share some tricks for the creation of a SQL table by using an XML file and importing data from an XML file to an SQL table.

These tricks can be easily implemented in everyday coding like ‘creating a DataTable using XML file’, ‘creating an SQL table using DataTable’, ‘importing rows from DataTable’ and ‘inserting row data into the SQL table’.

There are two ways in which we can import data from DataTable to SQL table. The first and the most common method is to insert data individually row by row; executing the query for each respective row, one at a time. The second option is to use the ‘BulkCopy’ feature of SQL. The BulkCopy feature allows us to copy all the rows present in the DataTable and add them to the SQL table at one go. We will use this feature of SQL and import data from an XML file to an SQL table.

Targeted Audiences

The targeted audience is: people with basic knowledge of C# Windows Applications.

To-do list

  • Make an Asp.net C# Winform application
  • Create a Windows Form
  • Add the controls
  • Code

Explanation

We will create a New Windows Form Application in C# and give it a suitable name.

 
 
In this example we gave the project name as “XMLtoDatabase”.

After creating project, we will get Windows Application Form, ‘Form1’, by default in our solution explorer. Since we are creating a single form application, we do not need to create another new form.

Now, add controls to the form as shown in below image.

 

In this example we added a TextBox for XML file path, a Button to browse and select the XML file from our local drive, an OpenFileDialog component to handle the file selection, an Import Button which will perform the main functionality of our project, and a ProgressBar to show the progress rate of our application function.

After designing the form, we can start coding. We will follow some simple steps to get a better understand of our project.

Before starting the code we need to configure Database connection.

  1. Create DataBase SampleDB 

We initially created a database in SQL Server with the name of “SampleDB”.

After creating the Database we will add the following ConnectionString in our App.config file.

  1.  <connectionStrings>  
  2.   
  3. <add name="strcon" connectionString="Data Source=YourSqlServerName;Initial Catalog=SampleDB;Integrated Security=True"  
  4. providerName="System.Data.SqlClient" />  
  5.   
  6. </connectionStrings> 

We will refer the same ConnectionString while writing the code for our WinForm. We also changed the Data Source (Server Name) with our local database server name.

The Next step is adding the required Namespace in code.

  1. using System.IO;  
  2. using System.Data.SqlClient;  
  3. using System.Configuration;  
  4. using System.Xml; 

After adding the controls and the Namespace, we will start writing the code for each of our controls. First we will create an event of the Browse button.

  1. // File Browser Button Click  
  2.        private void btnBrowse_Click(object sender, EventArgs e)  
  3.        {  
  4.            if (OFD.ShowDialog() == System.Windows.Forms.DialogResult.OK)  
  5.                txtFilePath.Text = OFD.FileName;  
  6.   
  7.        }  

The above code displays the selected file with its path in the FilePath TextBox.

We will then create an Event for the Import Button, and write the code for checking the XML file location. We will generate a DataTable by using that file. Once we get the DataTable, we will assign it a name similar to the name of our XML file.

  1. private void btnImport_Click(object sender, EventArgs e)  
  2. {  
  3.     string XMlFile = txtFilePath.Text;  
  4.     if (File.Exists(XMlFile))  
  5.     {  
  6.         // Conversion Xml file to DataTable  
  7.         DataTable dt = CreateDataTableXML(XMlFile);  
  8.         if (dt.Columns.Count == 0)  
  9.             dt.ReadXml(XMlFile);  
  10.   
  11.         // Creating Query for Table Creation  
  12.         string Query = CreateTableQuery(dt);  
  13.         SqlConnection con = new SqlConnection(StrCon);  
  14.         con.Open();  
  15.   
  16.         // Deletion of Table if already Exist  
  17.         SqlCommand cmd = new SqlCommand("IF OBJECT_ID('dbo." + dt.TableName + "', 'U') IS NOT NULL DROP TABLE dbo." + dt.TableName + ";", con);  
  18.         cmd.ExecuteNonQuery();  
  19.   
  20.         // Table Creation  
  21.         cmd = new SqlCommand(Query, con);  
  22.         int check = cmd.ExecuteNonQuery();  
  23.         if (check != 0)  
  24.         {  
  25.         // Copy Data from DataTable to Sql Table  
  26.         using (var bulkCopy = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.KeepIdentity))  
  27.         {  
  28.             // my DataTable column names match my SQL Column names, so I simply made this loop. However if your column names don't match, just pass in which datatable name matches the SQL column name in Column Mappings  
  29.             foreach (DataColumn col in dt.Columns)  
  30.             {  
  31.                 bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);  
  32.             }  
  33.   
  34.             bulkCopy.BulkCopyTimeout = 600;  
  35.             bulkCopy.DestinationTableName = dt.TableName;  
  36.             bulkCopy.WriteToServer(dt);  
  37.         }  
  38.   
  39.             MessageBox.Show("Table Created Successfully");  
  40.         }  
  41.         con.Close();  
  42.     }  
  43.   

In the below function we will generate the DataTable from the XML file by using simple XmlDocument code.

  1. // Conversion Xml file to DataTable  
  2. public DataTable CreateDataTableXML(string XmlFile)  
  3. {  
  4.     XmlDocument doc = new XmlDocument();  
  5.   
  6.     doc.Load(XmlFile);  
  7.   
  8.     DataTable Dt = new DataTable();  
  9.   
  10.     try  
  11.     {  
  12.         Dt.TableName = GetTableName(XmlFile);  
  13.         XmlNode NodoEstructura = doc.DocumentElement.ChildNodes.Cast<XmlNode>().ToList()[0];  
  14.         progressBar1.Maximum = NodoEstructura.ChildNodes.Count;  
  15.         progressBar1.Value = 0;  
  16.         foreach (XmlNode columna in NodoEstructura.ChildNodes)  
  17.         {  
  18.             Dt.Columns.Add(columna.Name, typeof(String));  
  19.             Progress();  
  20.         }  
  21.   
  22.         XmlNode Filas = doc.DocumentElement;  
  23.         progressBar1.Maximum = Filas.ChildNodes.Count;  
  24.         progressBar1.Value = 0;  
  25.         foreach (XmlNode Fila in Filas.ChildNodes)  
  26.         {  
  27.             List<string> Valores = Fila.ChildNodes.Cast<XmlNode>().ToList().Select(x => x.InnerText).ToList();  
  28.             Dt.Rows.Add(Valores.ToArray());  
  29.             Progress();  
  30.         }  
  31.     }  
  32.     catch (Exception ex)  
  33.     {  
  34.   
  35.     }  
  36.     return Dt;  
  37. }  

In this function, we are extracting XML nodes and by using these nodes we are structuring the DataTable. We are using XML node’s value to create XML rows. Also, we are showing the progress of this function in the ProgressBar.

After Generation of DataTable, we have to check whether the same table already exists in the database. If it already exists, then we will have to delete the table and re-create the same. To do this, we need the table creation query that we are getting from the following function.

  1. // Getting Query for Table Creation  
  2.      public string CreateTableQuery(DataTable table)  
  3.      {  
  4.          string sqlsc = "CREATE TABLE " + table.TableName + "(";  
  5.          progressBar1.Maximum = table.Columns.Count;  
  6.          progressBar1.Value = 0;  
  7.          for (int i = 0; i < table.Columns.Count; i++)  
  8.          {  
  9.              sqlsc += "[" + table.Columns[i].ColumnName + "]";  
  10.              string columnType = table.Columns[i].DataType.ToString();  
  11.              switch (columnType)  
  12.              {  
  13.                  case "System.Int32":  
  14.                      sqlsc += " int ";  
  15.                      break;  
  16.                  case "System.Int64":  
  17.                      sqlsc += " bigint ";  
  18.                      break;  
  19.                  case "System.Int16":  
  20.                      sqlsc += " smallint";  
  21.                      break;  
  22.                  case "System.Byte":  
  23.                      sqlsc += " tinyint";  
  24.                      break;  
  25.                  case "System.Decimal":  
  26.                      sqlsc += " decimal ";  
  27.                      break;  
  28.                  case "System.DateTime":  
  29.                      sqlsc += " datetime ";  
  30.                      break;  
  31.                  case "System.String":  
  32.                  default:  
  33.                      sqlsc += string.Format(" nvarchar({0}) ", table.Columns[i].MaxLength == -1 ? "max" : table.Columns[i].MaxLength.ToString());  
  34.                      break;  
  35.              }  
  36.              if (table.Columns[i].AutoIncrement)  
  37.                  sqlsc += " IDENTITY(" + table.Columns[i].AutoIncrementSeed.ToString() + "," + table.Columns[i].AutoIncrementStep.ToString() + ") ";  
  38.              if (!table.Columns[i].AllowDBNull)  
  39.                  sqlsc += " NOT NULL ";  
  40.              sqlsc += ",";  
  41.   
  42.              Progress();  
  43.          }  
  44.          return sqlsc.Substring(0, sqlsc.Length - 1) + "\n)";  
  45.      }  

In the above function we are generating a query for creating a table using a DataTable. We have then assigned the same name to our SQL table as our DataTable's name. Also, SQL table's column names and their data types are assigned according to the DataTable’s column names and data types.

After the creation of table, we will add the XML data to the SQL table. From the two options mentioned in the beginning, the preferable one is using the “BulkCopy” feature of SQL.

  1. // Copy Data from DataTable to Sql Table  
  2.                 using (var bulkCopy = new SqlBulkCopy(con.ConnectionString, SqlBulkCopyOptions.KeepIdentity))  
  3.                 {  
  4.                     // my DataTable column names match my SQL Column names, so I simply made this loop. However if your column names don't match, just pass in which datatable name matches the SQL column name in Column Mappings  
  5.                     foreach (DataColumn col in dt.Columns)  
  6.                     {  
  7.                         bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);  
  8.                     }  
  9.   
  10.                     bulkCopy.BulkCopyTimeout = 600;  
  11.                     bulkCopy.DestinationTableName = dt.TableName;  
  12.                     bulkCopy.WriteToServer(dt);  
  13.                 }  

In Bulk Copy function first we are checking the column name by mapping the columns and assigning the SQL table name as per the DataTable’s Table Name.

Output

The final output will appear as shown below,

 
 
 
Conclusion

In this article, you learnted the basic concepts of XML, DataTable, SQL Database connectivity, and Progress Bar Integration and the working of a Progress Bar.

This project can act as a sub-project or a module to any other project. You can integrate the concept within any of your projects where you are creating an SQL table dynamically by using XML files. This will erase the need to write the code manually each time. You simply have to make a library of the above code that you can implement with your project. This will give you the flexibility to easily utilize the functions and/or classes as per your requirements.

Hope this article helps you and you like it. I have also attached the Project source code, which you can download for your reference.

Thank you for reading.

Don’t forget to give your valuable feedback in the comment section.