Export reach row as XML with Elements

tdignan87

Member
Joined
Jul 8, 2019
Messages
14
Programming Experience
Beginner
Hi everyone,
I have just found this forum! looking forward to checking this place out.

I have a datagridview (unbound) that exports successfully into XML with elements. I want to however; run the XML for every line in the datagridview that contains data and treat it as a individual XML import. Basically the code to loop for the next row.
See example for code.

try
{

foreach (DataGridViewRow row in dataGridView1.Rows)

{



XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;


// Initialize the XmlWriter.
// Dim XmlWrt As XmlWriter = XmlWriter.Create("COMMODITY.xml", settings)
XmlWriter XmlWrt = XmlWriter.Create(ExportLocTxt.Text, settings);
{
var withBlock = XmlWrt;

// Write the Xml declaration.
withBlock.WriteStartDocument();

// Write a comment.
withBlock.WriteComment("Stevens Container Import. iSchedulr");

// Write the root element.
withBlock.WriteStartElement("stevens");

// Start our first person.
withBlock.WriteStartElement("containers");


withBlock.WriteStartElement("container");

// The person nodes.



withBlock.WriteStartElement("code");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[0].Value.ToString());

// withBlock.WriteString(row.Cells[0].Value.ToString());
withBlock.WriteEndElement();



withBlock.WriteStartElement("name");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[1].Value.ToString());
// withBlock.WriteString(row.Cells[1].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("description");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[2].Value.ToString());
// withBlock.WriteString(row.Cells[2].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("tare");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[3].Value.ToString());
// withBlock.WriteString(row.Cells[3].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("type");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[5].Value.ToString());
// withBlock.WriteString(row.Cells[5].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("group");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[4].Value.ToString());
// withBlock.WriteString(row.Cells[4].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("location");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[6].Value.ToString());
// withBlock.WriteString(row.Cells[6].Value.ToString());
withBlock.WriteEndElement();

// The end of this person.
withBlock.WriteEndElement();

withBlock.WriteEndElement();

// Close the XmlTextWriter.
withBlock.WriteEndDocument();
withBlock.Close();
 

Sheepings

Senior Programmer
Joined
Sep 5, 2018
Messages
166
Location
UK
Programming Experience
10+
Can you please edit your post and re-paste your code between code tags, just like this ::



Doing this helps to keep the original indentation as well as using the color legends makes the code more readable for us.
 

tdignan87

Member
Joined
Jul 8, 2019
Messages
14
Programming Experience
Beginner
Can you please edit your post and re-paste your code between code tags, just like this ::



Doing this helps to keep the original indentation as well as using the color legends makes the code more readable for us.
Done now.
Apologies


C#:
try
{

foreach (DataGridViewRow row in dataGridView1.Rows)

{



XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;


// Initialize the XmlWriter.
// Dim XmlWrt As XmlWriter = XmlWriter.Create("COMMODITY.xml", settings)
XmlWriter XmlWrt = XmlWriter.Create(ExportLocTxt.Text, settings);
{
var withBlock = XmlWrt;

// Write the Xml declaration.
withBlock.WriteStartDocument();

// Write a comment.
withBlock.WriteComment("Stevens Container Import. iSchedulr");

// Write the root element.
withBlock.WriteStartElement("stevens");

// Start our first person.
withBlock.WriteStartElement("containers");


withBlock.WriteStartElement("container");

// The person nodes.



withBlock.WriteStartElement("code");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[0].Value.ToString());

// withBlock.WriteString(row.Cells[0].Value.ToString());
withBlock.WriteEndElement();



withBlock.WriteStartElement("name");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[1].Value.ToString());
// withBlock.WriteString(row.Cells[1].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("description");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[2].Value.ToString());
// withBlock.WriteString(row.Cells[2].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("tare");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[3].Value.ToString());
// withBlock.WriteString(row.Cells[3].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("type");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[5].Value.ToString());
// withBlock.WriteString(row.Cells[5].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("group");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[4].Value.ToString());
// withBlock.WriteString(row.Cells[4].Value.ToString());
withBlock.WriteEndElement();

withBlock.WriteStartElement("location");
withBlock.WriteString(dataGridView1.CurrentRow.Cells[6].Value.ToString());
// withBlock.WriteString(row.Cells[6].Value.ToString());
withBlock.WriteEndElement();

// The end of this person.
withBlock.WriteEndElement();

withBlock.WriteEndElement();

// Close the XmlTextWriter.
withBlock.WriteEndDocument();
withBlock.Close();
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
214
Location
Virginia Beach, VA
Programming Experience
10+
You are already doing more or less what you want. Your foreach loop that starts at line 4 and presumably ends past line 84 goes over each row in your data grid view. For each iteration of your loop, you are creating an XML file and writing to it. The only problem I see there is that you keep writing to the same file because on line 16, you are not doing anything to create a new file name as the destination.

As to why you would want multiple XML files where each file is a line from your data grid view, I'm having a hard time reconciling in my head, but that is what you said you wanted to do.

Now, if what you wanted was really just one output file XML file , and you wanted multiple rows of data within that single file, then you would simply move the code that initially opens the file for writing, and creates the root element outside of the foreach loop, and then with in the loop, write out each row, write out a person element.

(As an aside, there is a slightly cleaner way to write out the data using XML serialization, but it may not be worth the effort depending on how your data is loaded into the data grid view.)
 

tdignan87

Member
Joined
Jul 8, 2019
Messages
14
Programming Experience
Beginner
Hi Skydiver.
Thanks for your reply mate.
It always exports just one row. From reading your comments it makes more sense to export with just one XML containing the root element outside for each loop, and within the loop, write out each row and the individual element.
I've never used that no
What happens is the user uploads an excel file into the DGV; which populates it with data; they then click export which takes the DGV and exports it as XML.
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
214
Location
Virginia Beach, VA
Programming Experience
10+
The reasons why your current code is always writing out the same row over and over again is because you are using CurrentRow, and as I said earlier, you keep overwriting the same file.

XML serialization is likely not going to be worth it if the user is pasting in or uploading the data directly into the DGV.

One way to trim down your code for the places where you start an element, write a value, and then immediately close the element would be to use the WriteElementString() so that you can change:
Code:
withBlock.WriteStartElement("tare");
withBlock.WriteString(row.Cells[3].Value.ToString());
withBlock.WriteEndElement();
to
Code:
withBlock.WriteElementString("tare", row.Cells[3].Value.ToString());

To even further trim down your code, if your DGV column Name property (not HeaderText property) matches the XML element name you could do the following:
Code:
var containerElementNames = new string [] { "code", "name", "description", "tare", "type", "group", "location" };
foreach (string name in containerElementNames)
    withBlock.WriteElementString(name, row.Cells[name].Value.ToString());
 

tdignan87

Member
Joined
Jul 8, 2019
Messages
14
Programming Experience
Beginner
Hi Skydiver.
Thanks for getting back to me again

I tried the

C#:
withBlock.WriteElementString("tare", row.Cells[3].Value.ToString());
I am now getting this error

System.NullReferenceException: 'Object reference not set to an instance of an object.'

Is this because it thinks the cell is null?

Thanks
 

Sheepings

Senior Programmer
Joined
Sep 5, 2018
Messages
166
Location
UK
Programming Experience
10+
There is a debugger link in my signature. I suggest reading it if you are unfamiliar with debugging. Put a break point on the error and when it breaks hover your mouse over it and check which or if it is null and handle how you wish to deal with it there and then.
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
214
Location
Virginia Beach, VA
Programming Experience
10+
If you are using Visual Studio, you can hover each of the parts there to find out which one is null when the exception is thrown.

If you have that code within the foreach (DataGridViewRow row in dataGridView1.Rows), then row shouldn't be null. (As far as I know it follows the modern C# approach of not returning a null within a collection, unlike older .NET Framework 1.1 and 2.0.

If you have at least 4 columns, then row.Cells[3] shouldn't be null.

Most likely row.Cells[3].Value is null.
 

tdignan87

Member
Joined
Jul 8, 2019
Messages
14
Programming Experience
Beginner
Hi Guys
Please see code again with the changes i have done. Exception error is this

"System.NullReferenceException: 'Object reference not set to an instance of an object.'

System.Windows.Forms.DataGridViewCell.Value.get returned null."

Code example:

Example:
            {
                //if (row.Cells[0].Value == null || row.Cells[0].Value == DBNull.Value) return;
                //  try
                {




                    {

                        foreach (DataGridViewRow row in dataGridView1.Rows)
                        {

                            XmlWriterSettings settings = new XmlWriterSettings();
                        settings.Indent = true;


                        // Initialize the XmlWriter.
                        // Dim XmlWrt As XmlWriter = XmlWriter.Create("COMMODITY.xml", settings)
                        XmlWriter XmlWrt = XmlWriter.Create(ExportLocTxt.Text, settings);
                        {
                            var withBlock = XmlWrt;

                            //   Write the Xml declaration.
                            withBlock.WriteStartDocument();

                            //   Write a comment.
                            withBlock.WriteComment("Stevens Container Import. iSchedulr");

                            //    Write the root element.
                            withBlock.WriteStartElement("stevens");

                            //    Start our first person.
                            withBlock.WriteStartElement("containers");


                            withBlock.WriteStartElement("container");

                                // The person nodes.


                                var containerElementNames = new string[] { "code", "name", "description", "tare", "type", "group", "location" };
                                foreach (string name in containerElementNames)


                                withBlock.WriteElementString("code", row.Cells[0].Value.ToString());
                                //  withBlock.WriteStartElement("code");
                                //withBlock.WriteString(dataGridView1.CurrentRow.Cells[0].Value.ToString());
                                //     withBlock.WriteString(row.Cells[0].Value.ToString());
                              //withBlock.WriteEndElement();



                          
                                    withBlock.WriteElementString("name", row.Cells[1].Value.ToString());
                                //  withBlock.WriteStartElement("name");
                                // withBlock.WriteString(dataGridView1.CurrentRow.Cells[1].Value.ToString());
                                //  withBlock.WriteString(row.Cells[1].Value.ToString());
                            //  withBlock.WriteEndElement();


                                withBlock.WriteElementString("description", row.Cells[2].Value.ToString());
                                // withBlock.WriteStartElement("description");
                              //withBlock.WriteString(dataGridView1.CurrentRow.Cells[2].Value.ToString());
                                    //   withBlock.WriteString(row.Cells[2].Value.ToString());
                               //   withBlock.WriteEndElement();

                                withBlock.WriteElementString("tare", row.Cells[3].Value.ToString());
                              //withBlock.WriteStartElement("tare");
                                //  withBlock.WriteString(dataGridView1.CurrentRow.Cells[3].Value.ToString());
                                    //  withBlock.WriteString(row.Cells[3].Value.ToString());
                               // withBlock.WriteEndElement();

                                //  withBlock.WriteStartElement("type");
                                withBlock.WriteElementString("type", row.Cells[5].Value.ToString());
                           //   withBlock.WriteString(dataGridView1.CurrentRow.Cells[5].Value.ToString());
                                    // withBlock.WriteString(row.Cells[5].Value.ToString());
                              //    withBlock.WriteEndElement();

                                withBlock.WriteElementString("group", row.Cells[4].Value.ToString());
                              //withBlock.WriteStartElement("group");
                                 // withBlock.WriteString(dataGridView1.CurrentRow.Cells[4].Value.ToString());
                                    //  withBlock.WriteString(row.Cells[4].Value.ToString());
                               //   withBlock.WriteEndElement();

                                withBlock.WriteElementString("location", row.Cells[6].Value.ToString());
                             // withBlock.WriteStartElement("location");
                                //  withBlock.WriteString(dataGridView1.CurrentRow.Cells[6].Value.ToString());
                                    // withBlock.WriteString(row.Cells[6].Value.ToString());
                                //  withBlock.WriteEndElement();

                                    //   The end of this person.
                                    withBlock.WriteEndElement();

                                    withBlock.WriteEndElement();

                                    //   Close the XmlTextWriter.
                                    withBlock.WriteEndDocument();
                                    withBlock.Close();
                                
                            }

                        }

                        {



                            TimerTxt.Text = "Export Successful";

                        }
                    }
 

Skydiver

Well-known member
Joined
Apr 6, 2019
Messages
214
Location
Virginia Beach, VA
Programming Experience
10+
And again, we are telling you to use your debugger. Check the values of the variables:
row
row.Cells[0]
row.Cells[0].Value
 

Sheepings

Senior Programmer
Joined
Sep 5, 2018
Messages
166
Location
UK
Programming Experience
10+
Introduce some conditional logic to check these
row.Cells.Value != null
row.Cells.Value != DBNull.Value
You might want to check String.IsNullOrWhiteSpace on the cell value too.
On line 45, run some checks to see if they are not null, then process them, else skip them or handle the null value.

Again, refer to the guidance you got on post 8 and 9.
 

tdignan87

Member
Joined
Jul 8, 2019
Messages
14
Programming Experience
Beginner
Hi Guys
If i have "allow user to add rows" = disabled then there is no errors and it exports the file; just blank data within the elements though.. >.< argh.
I put allow users to add rows back on, put a breakpoint and watch at the relevant line.

578
 

Sheepings

Senior Programmer
Joined
Sep 5, 2018
Messages
166
Location
UK
Programming Experience
10+
I've no idea what way my text got formatted in the last post obviously due to my lack of code tags... but its still very clear what you're being told to do. How hard is it for you to write a statement checking the values of the iteration before you attempt to use them? If you have a null value, you will need to handle it. You can't do that without first checking what the value type is. Your code could also be simplified, but I don't feel like putting in the effort if you too are not willing either.

if (row.Cells[i].Value != null || row.Cells[i].Value != DBNull.Value etc etc check for more conditions as outlined on my last post)

From the beginning of your xmlwriter code to the end of the xmlwriter closing bracket } there should be the above statement. Please put some effort in, we all like to see some effort. The above line will prevent nulls being processed. I am sure you know how to write if statements and how they work? If not, there is a helpful link in my signature for its documentation.

If i have "allow user to add rows" = disabled then there is no errors and it exports the file; just blank data
Nobody suggested you do that. But you could do as suggested or else struggle.
 

tdignan87

Member
Joined
Jul 8, 2019
Messages
14
Programming Experience
Beginner
Sorry its not that i am not putting in the effort; I am learning and trying my best. I will get there.....
Yeah i am familiar with writing IF statements.
I will give that a bash; and update my findings.

Thank you for your patience with this newbie!
 

JohnH

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
519
Location
Norway
Programming Experience
10+
If i have "allow user to add rows" = disabled then there is no errors
To exclude the "new row" row you can check row.IsNewRow.

If a cell.Value can be null you can't do .ToString directly, null.ToString will cause NullReferenceException. One option is to use the null conditional operator like this value?.ToString(), this will return null if the value is null and that is ok to use as input for WriteElementString, or else the value as string. Another could be to convert using Convert.ToString method instead.
 
Top Bottom