Help: I can read XML into Datagrid but get error writing from Datagrid to XML file
Hello, I am fairly new to programming and I need some serious help. I have spent over 8hours on this and still don't know what I'm doing wrong.
I am trying to create an xml editor that read and write xml. my code reads the xml with no problem and allows me to create new rows but when I try to "write" it over I get the following error: "Token StartElement in state Epilog would result in an invalid XML document"
Private Sub btnWriteXml_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ds As DataSet = DirectCast(dataGrid1.DataSource, DataSet)
ds.WriteXml("XMLFileOut.xml", XmlWriteMode.IgnoreSchema)
End Sub
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Without seeing what your dataset looks like it is impossible to say. I suggest you inspect your dataset. Maybe you have some invalid characters in it. Most likely in one of the new rows. Try to save it without adding a new row.
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Hi MarMan, thanks a lot for your reply.
please elaborate on what you mean by inserting my dataset. this is my complete code that reads and writes the xml:
Code:
Private Sub btnReadXml_Click(sender As Object, e As System.EventArgs)
Dim ds As New DataSet()
ds.ReadXml("macros.xml", XmlReadMode.InferSchema)
dataGrid1.SetDataBinding(ds, "macro")
End Sub
Private Sub btnWriteXml_Click(sender As Object, e As System.EventArgs)
Dim ds As DataSet = DirectCast(dataGrid1.DataSource, DataSet)
ds.WriteXml("XMLFileOut.xml", XmlWriteMode.IgnoreSchema)
End Sub
it saves without any problem when I don't add a new row.
Thanks
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Here is an example using two DataGridView controls that reads in data from your XML file (see below for modified XML file with two rows).
Note this code was written with VS2008, Framework 3.5 Option Strict On
Code:
Public Class Form2
Private SourceFile As String = IO.Path.Combine(Application.StartupPath, "macros.xml")
Private OutFile1 As String = IO.Path.Combine(Application.StartupPath, "XMLFileOut1.xml")
Private OutFile2 As String = IO.Path.Combine(Application.StartupPath, "XMLFileOut2.xml")
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If IO.File.Exists(SourceFile) Then
Dim DataSet1 As New DataSet
DataSet1.ReadXml(SourceFile)
DataGridView1.DataSource = DataSet1.Tables(0)
DataGridView2.DataSource = DataSet1.Tables(1)
Else
MessageBox.Show(String.Format("Failed to locate {0}{1}{0}Please correct.", _
Environment.NewLine, SourceFile, Environment.NewLine))
Button1.Enabled = False
Button2.Enabled = False
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim CopyDataTable = DirectCast(DataGridView1.DataSource, DataTable)
Dim ds As New DataSet
Dim dt1 = CopyDataTable.Clone
For Each row As DataRow In CopyDataTable.Rows
dt1.ImportRow(row)
Next
ds.Tables.Add(dt1)
CopyDataTable = DirectCast(DataGridView2.DataSource, DataTable)
Dim dt2 = CopyDataTable.Clone
For Each row As DataRow In CopyDataTable.Rows
dt2.ImportRow(row)
Next
ds.Tables.Add(dt2)
ds.WriteXml(OutFile1, XmlWriteMode.IgnoreSchema)
Process.Start("notepad", OutFile1)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim DataTable1 = DirectCast(DataGridView1.DataSource, DataTable)
Dim DataTable2 = DirectCast(DataGridView2.DataSource, DataTable)
Dim Contents = _
<?xml version="1.0" standalone="yes"?>
<MyMacros>
</MyMacros>
For Index As Integer = 0 To DataTable1.Rows.Count - 1
Dim MyStructure = _
<MacroList identifier=<%= DataTable1.Rows(Index).Field(Of String)("identifier") %>>
<macro>
<macro_identifier><%= DataTable2.Rows(Index).Field(Of String)("macro_identifier") %></macro_identifier>
<replacement_string><%= DataTable2.Rows(Index).Field(Of String)("replacement_string") %></replacement_string>
<date_deleted><%= DataTable2.Rows(Index).Field(Of String)("date_deleted") %></date_deleted>
<macro_seq><%= DataTable2.Rows(Index).Field(Of String)("macro_seq") %></macro_seq>
<is_dirty><%= DataTable2.Rows(Index).Field(Of String)("is_dirty") %></is_dirty>
</macro>
</MacroList>
Contents.<MyMacros>(0).Add(MyStructure)
Next
Dim FinalData As String = String.Concat("<?xml version=""1.0"" standalone=""yes""?>", Contents.ToString)
IO.File.WriteAllText(OutFile2, _
String.Concat("<?xml version=""1.0"" standalone=""yes""?>", _
Environment.NewLine, Contents.ToString))
Process.Start("notepad", OutFile2)
End Sub
End Class
If the data in the first table had a primary key which was also in rows in the child table you could create a master detail view with the two DataGridView controls which I am guessing is not needed in a DataGrid (which is an outdated control).
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Originally Posted by kevininstructor
Here is an example using two DataGridView controls that reads in data from your XML file (see below for modified XML file with two rows).
Note this code was written with VS2008, Framework 3.5 Option Strict On
Code:
Public Class Form2
Private SourceFile As String = IO.Path.Combine(Application.StartupPath, "macros.xml")
Private OutFile1 As String = IO.Path.Combine(Application.StartupPath, "XMLFileOut1.xml")
Private OutFile2 As String = IO.Path.Combine(Application.StartupPath, "XMLFileOut2.xml")
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If IO.File.Exists(SourceFile) Then
Dim DataSet1 As New DataSet
DataSet1.ReadXml(SourceFile)
DataGridView1.DataSource = DataSet1.Tables(0)
DataGridView2.DataSource = DataSet1.Tables(1)
Else
MessageBox.Show(String.Format("Failed to locate {0}{1}{0}Please correct.", _
Environment.NewLine, SourceFile, Environment.NewLine))
Button1.Enabled = False
Button2.Enabled = False
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim CopyDataTable = DirectCast(DataGridView1.DataSource, DataTable)
Dim ds As New DataSet
Dim dt1 = CopyDataTable.Clone
For Each row As DataRow In CopyDataTable.Rows
dt1.ImportRow(row)
Next
ds.Tables.Add(dt1)
CopyDataTable = DirectCast(DataGridView2.DataSource, DataTable)
Dim dt2 = CopyDataTable.Clone
For Each row As DataRow In CopyDataTable.Rows
dt2.ImportRow(row)
Next
ds.Tables.Add(dt2)
ds.WriteXml(OutFile1, XmlWriteMode.IgnoreSchema)
Process.Start("notepad", OutFile1)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim DataTable1 = DirectCast(DataGridView1.DataSource, DataTable)
Dim DataTable2 = DirectCast(DataGridView2.DataSource, DataTable)
Dim Contents = _
<?xml version="1.0" standalone="yes"?>
<MyMacros>
</MyMacros>
For Index As Integer = 0 To DataTable1.Rows.Count - 1
Dim MyStructure = _
<MacroList identifier=<%= DataTable1.Rows(Index).Field(Of String)("identifier") %>>
<macro>
<macro_identifier><%= DataTable2.Rows(Index).Field(Of String)("macro_identifier") %></macro_identifier>
<replacement_string><%= DataTable2.Rows(Index).Field(Of String)("replacement_string") %></replacement_string>
<date_deleted><%= DataTable2.Rows(Index).Field(Of String)("date_deleted") %></date_deleted>
<macro_seq><%= DataTable2.Rows(Index).Field(Of String)("macro_seq") %></macro_seq>
<is_dirty><%= DataTable2.Rows(Index).Field(Of String)("is_dirty") %></is_dirty>
</macro>
</MacroList>
Contents.<MyMacros>(0).Add(MyStructure)
Next
Dim FinalData As String = String.Concat("<?xml version=""1.0"" standalone=""yes""?>", Contents.ToString)
IO.File.WriteAllText(OutFile2, _
String.Concat("<?xml version=""1.0"" standalone=""yes""?>", _
Environment.NewLine, Contents.ToString))
Process.Start("notepad", OutFile2)
End Sub
End Class
If the data in the first table had a primary key which was also in rows in the child table you could create a master detail view with the two DataGridView controls which I am guessing is not needed in a DataGrid (which is an outdated control).
Hi Kevin, thanks once again. the code is not reading the new xml file you modified but it reads my old xml with your code. it throws "Object reference not set to an instance of an object." error at
Code:
Dim dt1 = CopyDataTable.Clone
when I use your code to open my xml, it reads it with no problem in one of the gridview. but when I input texts in new row and save it, it doesn't save to the xml file or update the second gridview. am I doing something wrong?
Thanks for your help
Last edited by The Intern; Oct 16th, 2011 at 02:43 PM.
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Originally Posted by The Intern
Hi Kevin, thanks once again. the code is not reading the new xml file you modified but it reads my old xml with your code. it throws "Object reference not set to an instance of an object." error at
Code:
Dim dt1 = CopyDataTable.Clone
when I use your code to open my xml, it reads it with no problem in one of the gridview. but when I input texts in new row and save it, it doesn't save to the xml file or update the second gridview. am I doing something wrong?
Thanks for your help
Hard to say what you are doing to cause this behavior. Study my attached project which has changed just a tad in that it used two BindingSources and one new (to you) language extension method. Compile, run, press the add then the export button. Do not alter the project until you have done the above as it works upon delivery to you.
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Originally Posted by The Intern
it saves without any problem when I don't add a new row.
Thanks
That is a very significant clue. We can narrow it down further. Can you edit a row? Change a single character? How are you adding the row? Check out what the new row looks like compared to another row. What is different? Can you add a row that is identical to a row that does save? If you can and it does not save then something is missing. Some metadata perhaps?
I gave you more questions than you gave us!! It should help you debug.
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Thanks everyone for your input. I am currently working with Kevin attached project. it is inline with what I am trying to accomplish. Now I am trying to find a way to add a new 'editable' row instead of the static ones in his code and also have the new added row display in the datagridview instead of having them display as "another test", "new" and so on
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Originally Posted by The Intern
Thanks everyone for your input. I am currently working with Kevin attached project. it is inline with what I am trying to accomplish. Now I am trying to find a way to add a new 'editable' row instead of the static ones in his code and also have the new added row display in the datagridview instead of having them display as "another test", "new" and so on
Examine this code which does adding new rows and editing existing rows using a modal dialog rather than directly in the DataGridViews. Note that during adding and editing you need to use some form of assertion to validate that data entered is correct along with checks to ensure data coming in from the XML is correct, for instance if a date falls outside of the DatePicker an exception will be raised etc.
Re: Help: I can read XML into Datagrid but get error writing from Datagrid to XML fil
Originally Posted by kevininstructor
Examine this code which does adding new rows and editing existing rows using a modal dialog rather than directly in the DataGridViews. Note that during adding and editing you need to use some form of assertion to validate that data entered is correct along with checks to ensure data coming in from the XML is correct, for instance if a date falls outside of the DatePicker an exception will be raised etc.
Thanks a lot Kevin. this is what I needed and it will guide me to what I am trying to accomplish. thanks everyone for your time. I greatly appreciate it!