Click here to Skip to main content
15,887,596 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
Hi am trying to save a datagridview to XML file using XDocument but the problem is when i click export button the datagridview gets clear and the exported XML file is empty

This button fill datagridview from multiple textboxs :

private void add_Click(object sender, EventArgs e)
     {
         int n = dataGridView1.Rows.Add();
    
         dataGridView1.Rows[n].Cells[0].Value = txtOne.Text;
         dataGridView1.Rows[n].Cells[1].Value = txtTwo.Text;
         dataGridView1.Rows[n].Cells[2].Value = txtThree.Text; 
     }


This what am looking for as exported XML file:

<root>
 <table>
 <one>125</one>
 <two>125</two>
   <child>
     <three>987</three> 
   </child>
 </table>
 </root>


What I have tried:

private void Export_Click(object sender, EventArgs e)
    {
       
    const string FILENAME = @"c:\temp\test.xml";
    XDocument doc = new XDocument(
    new XDeclaration("1.0", "ISO-8859-1", null),
    new XElement("root",    
        dt.AsEnumerable().Select(row => new XElement("child", new object[]{
                new XElement("one",row[0]),
                new XElement("two",row[1]),
                new XElement("child",new XElement("three", row[2])),
                }));
    
    
    dataGridView1.DataSource = dt;
    doc.Save(FILENAME);
    SaveFileDialog saveFileDialog1 = new SaveFileDialog();
    saveFileDialog1.InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments);
    saveFileDialog1.Filter = "File Name |*.xml";
    saveFileDialog1.FilterIndex = 1;
    if (saveFileDialog1.ShowDialog() == DialogResult.OK)
    {
        doc.Save(saveFileDialog1.FileName);
    }
Posted
Updated 27-May-20 11:23am

Although Data Binding is the recommended way, you could do it like the example taken from: Export DataGridView to XML File without any DataSet or DataTable ...[^]
private DataTable GetDataTableFromDGV(DataGridView dgv) {
    var dt = new DataTable();

    foreach (DataGridViewColumn column in dgv.Columns) {
        if (column.Visible) {
            // You could potentially name the column based on the DGV column name (beware of dupes)
            // or assign a type based on the data type of the data bound to this DGV column.
            dt.Columns.Add();
        }
    }

    object[] cellValues = new object[dgv.Columns.Count];
    foreach (DataGridViewRow row in dgv.Rows) {
        for (int i = 0; i < row.Cells.Count; i++) {
            cellValues[i] = row.Cells[i].Value;
        }
        dt.Rows.Add(cellValues);
    }

    return dt;
}


And to save:
DataTable dT = GetDataTableFromDGV(DataGridView1);
           DataSet dS = new DataSet();
           dS.Tables.Add(dT);
           dS.WriteXml(File.OpenWrite("xml.xml"));


The DataSet is probably not needed, just use DataTable.WriteXml("xml.xml")
See: DataTable.WriteXml Method (System.Data) | Microsoft Docs[^]
 
Share this answer
 
v2
First of all, you'll never be good programmer, if you're trying to use the piece of code by copy-paste and without changing code on your own.

Second of all, your DataGridView control is bind to none DataSource, because you're adding rows directly!
C#
private void add_Click(object sender, EventArgs e)
{
         int n = dataGridView1.Rows.Add();
         //ignored lines!
}

See: Create an Unbound DataGridView Control - Windows Forms | Microsoft Docs[^]

Third of all, your xml structure is wrong! Instead of:
XML
<root>
 <table>
 <one>125</one>
 <two>125</two>
   <child>
     <three>987</three> 
   </child>
 </table>
 </root>

it should be something like:
XML
<root>
   <table>
     <row>
       <one>125</one>
       <two>128</two>
       <child>
         <three>987</three> 
       </child>
     </row>
     <row>
       <one>321</one>
       <two>216</two>
       <child>
         <three>999</three> 
       </child>
     </row>
   </table>
 </root>



So, if you would like to export unbound data into xml file, you have to loop through the collection of DataGridViewRows[^].

C#
private void Export_Click(object sender, EventArgs e)
{
    const string FILENAME = @"c:\temp\test.xml";
    XDocument doc = new XDocument(new XDeclaration("1.0", "ISO-8859-1", "yes"));
    XElement root = new XElement("root");
    XElement tbl = new XElement("table");
    List<XElement> entries = DataGridView1.Rows.Cast<DataGridViewRow>()
	.Select(row => new XElement("row", new XElement[]
		{
			new XElement("one", row.Cells[0].Value.ToString()),
			new XElement("two", row.Cells[1].Value.ToString()),
			new XElement("child", new XElement("three", row.Cells[2].Value.ToString()))
		}))
		.ToList();
    tbl.Add(entries);
    root.Add(tbl);
    doc.Add(root);
    doc.Save(FILENAME);
}


Good luck!
 
Share this answer
 
v2
Comments
colanlog 28-May-20 3:59am    
Thanks a lot, man. You saved me
Also for advice, this is my first project ✌
Maciej Los 28-May-20 4:02am    
You're very welcome.
Cheers!
Maciej

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900