0

I have a data table with the following columns.

    dataTable.Columns.Add("ID", typeof(string));
    dataTable.Columns.Add("File Name", typeof(string));
    dataTable.Columns.Add("Date Taken", typeof(string));
    dataTable.Columns.Add("Size", typeof(string));
    dataTable.Columns.Add("Unique", typeof(bool));

A data table is written to XML file as follows

if (dgView.DataSource is DataTable dataTable) // Ensure DataSource is a DataTable
{
    if (string.IsNullOrWhiteSpace(dataTable.TableName))
    {
        dataTable.TableName = "MyDataTable"; // Assign a name to avoid serialization error
    }

    string dataTime = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"); // Dynamic timestamp
    string defaultFolder = txtSort.Text.Trim(); // Default folder from txtSort
    string defaultFileName = $"{dataTime}.xml";

    using (SaveFileDialog saveFileDialog = new SaveFileDialog())
    {
        saveFileDialog.InitialDirectory = Directory.Exists(defaultFolder) ? defaultFolder : Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        saveFileDialog.FileName = defaultFileName;
        saveFileDialog.Filter = "XML Files (*.xml)|*.xml|All Files (*.*)|*.*";
        saveFileDialog.Title = "Save DataTable as XML";

        if (saveFileDialog.ShowDialog() == DialogResult.OK)
        {
            try
            {
                dataTable.WriteXml(saveFileDialog.FileName);
                MessageBox.Show($"Data saved to {saveFileDialog.FileName}", "Data Saved", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error saving data: {ex.Message}", "Save Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
else
{
    MessageBox.Show("No valid data table found in DataGridView.", "No Data", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}

The file is created as follows:

<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <MyDataTable>
    <ID>1</ID>
    <File_x0020_Name>H:\Image backup\TEST_SOURCE\01\IMG_7718(8).jpg</File_x0020_Name>
    <Date_x0020_Taken>Jan/17/2016 14:46:06</Date_x0020_Taken>
    <Size>0.673 MB</Size>
    <Unique>true</Unique>
  </MyDataTable>
  <MyDataTable>
    <ID>2</ID>
    <File_x0020_Name>H:\Image backup\TEST_SOURCE\01\IMG_7718(2).jpg</File_x0020_Name>
    <Date_x0020_Taken>Jan/17/2016 14:46:06</Date_x0020_Taken>
    <Size>0.673 MB</Size>
    <Unique>true</Unique>
  </MyDataTable>
  <MyDataTable>
    <ID>3</ID>
    <File_x0020_Name>H:\Image backup\TEST_SOURCE\01\IMG_7719(3).jpg</File_x0020_Name>
    <Date_x0020_Taken>Jan/17/2016 14:46:07</Date_x0020_Taken>
    <Size>1.045 MB</Size>
    <Unique>true</Unique>
  </MyDataTable>
  <MyDataTable>
    <ID>7</ID>
    <File_x0020_Name>H:\Image backup\TEST_SOURCE\01\IMG_7719(2).jpg</File_x0020_Name>
    <Date_x0020_Taken>Jan/17/2016 14:46:07</Date_x0020_Taken>
    <Size>1.045 MB</Size>
    <Unique>true</Unique>
  </MyDataTable>
</DocumentElement>

When I read the file as follows, no data is read. (NUmber of rows is 0.)

private void btnRetrieve_Click(object sender, EventArgs e)
{
    OpenFileDialog OpenFileDialog = new OpenFileDialog();
    if (OpenFileDialog.ShowDialog() == DialogResult.OK)
    {
        string fileName = OpenFileDialog.FileName;
        Task.Run(() =>
        {
            // Load the data from XML into the DataTable
            DataTable dataTable = new DataTable();
            dataTable.Columns.Add("ID", typeof(string));
            dataTable.Columns.Add("File_x0020_Name", typeof(string)); // Handle space as _x0020_
            dataTable.Columns.Add("Date_x0020_Taken", typeof(string)); // Handle space as _x0020_
            dataTable.Columns.Add("Size", typeof(string));
            dataTable.Columns.Add("Unique", typeof(bool));

            // Read the XML into the DataTable
            if (File.Exists(fileName))
            {
                try
                {
                    dataTable.ReadXml(fileName);

                    // Check if data has been loaded
                    if (dataTable.Rows.Count == 0)
                    {
                        this.Invoke(new Action(() =>
                        {
                            MessageBox.Show("The XML file was loaded, but no data was found.", "Data Load Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }));
                    }
                    else
                    {
                        // Populate the dictionary with data from the DataTable
                        ConcurrentDictionary<string, List<mediaFile>> g_allFiles = new ConcurrentDictionary<string, List<mediaFile>>();

                        foreach (DataRow row in dataTable.Rows)
                        {
                            mediaFile media = new mediaFile
                            {
                                id = row["ID"].ToString(),
                                fileName = row["File_x0020_Name"].ToString(),
                                exif_date = row["Date_x0020_Taken"].ToString(),
                                fileSize = row["Size"].ToString(),
                                unique = Convert.ToBoolean(row["Unique"])
                            };

                            // Extract the file extension (3 letters)
                            string fileExtension = Path.GetExtension(media.fileName)?.Substring(1, 3).ToLower();

                            if (!string.IsNullOrEmpty(fileExtension))
                            {
                                if (!g_allFiles.ContainsKey(fileExtension))
                                {
                                    g_allFiles[fileExtension] = new List<mediaFile>();
                                }

                                g_allFiles[fileExtension].Add(media);
                            }
                        }

                        dataTable.Columns["File_x0020_Name"].ColumnName = "File Name";
                        dataTable.Columns["Date_x0020_Taken"].ColumnName = "Date Taken";

                        // Update DataGridView with loaded data
                        this.Invoke(new Action(() =>
                        {
                            dgView.DataSource = dataTable;
                        }));
                    }
                }
                catch (Exception ex)
                {
                    // Handle errors in reading the XML
                    this.Invoke(new Action(() =>
                    {
                        MessageBox.Show($"Error reading the XML file: {ex.Message}", "File Read Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }));
                }
            }
            else
            {
                // If file not found, show a message on the UI thread
                this.Invoke(new Action(() =>
                {
                    MessageBox.Show("The specified file path does not exist.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }));
            }
        });
    }
    var k = g_allFiles;
}

What am I doing wrong here?

2
  • Did you try the read with a column name containing spaces instead of escaping them with e.g. "File_x0020_Name"? Just asking whether that is the result of "File Name" not working. Commented Jan 29 at 22:45
  • There is no reason to add column manually before reading the xml. So remove the 5 add columns statements. You are probably getting an exception. Commented Jan 29 at 22:52

1 Answer 1

3

A direct load into the DataTable is not working for your XML file sample. It is erroring out with the following error:

DataTable does not support schema inference from Xml

Please try the following solution that is using DataSet datatype as an intermediate object.

As @jdweng pointed out:

There is no reason to add column manually before reading the xml.

I tested your exact XML file, and it is working.

c#

void Main()
{
    const string xmlFilePath = @"e:\Temp\dataTable.xml";

    DataSet dataSet = new DataSet();

    dataSet.ReadXml(xmlFilePath);
    DataTable dataTable = dataSet.Tables[0];

    // Display the data
    foreach (DataRow row in dataTable.Rows)
    {
        foreach (DataColumn column in dataTable.Columns)
        {
            Console.Write($"{row[column]} ");
        }
        Console.WriteLine();
    }
}

Output

ID File Name Date Taken Size Unique
1 H:\Image backup\TEST_SOURCE\01\IMG_7718(8).jpg Jan/17/2016 14:46:06 0.673 MB true
2 H:\Image backup\TEST_SOURCE\01\IMG_7718(2).jpg Jan/17/2016 14:46:06 0.673 MB true
3 H:\Image backup\TEST_SOURCE\01\IMG_7719(3).jpg Jan/17/2016 14:46:07 1.045 MB true
7 H:\Image backup\TEST_SOURCE\01\IMG_7719(2).jpg Jan/17/2016 14:46:07 1.045 MB true
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.