A
Angelo Pacione
I have an interesting problem. I am synching and XMLDataDocument with
a Dataset. The XML data is fairly simple (see below). I load a
schema (using ReadXMLSchema) into the Dataset (as described in the MS
examples). Then I synch the dataset and the XMLDataDocument. Finally
the XML is loaded in to the XMLDataDocument. I then bind a textbox to
the "Surname" element and a datagrid to the "Employment" repeating
element
This is all working fine for me except one hitch. It seems that both
editing in the textbox or grid is fine. Also deleting a row from the
grid is fine as well. However 'inserting' a row into the Employment
grid (either manually or programatically - try adding one on the end
of the grid - you'll see) does not seem to place the new node into the
proper position in the XML hierarchy (it gets appended at the end of
the structure - just before the 'NewDatset' element). Note that I am
writing out the edited XML with the "Save" method for the
XMLDataDocument" object. I think there is something improper going on
in the data relations (as you can see I debugged them - they look
fine). Also note that I used the Schema Designer to make the XSD file
associated with this XML data. It just seems weird that editing and
deleting are resoved correctly within the hierarchy, but inserting is
not.
All the code and XML is found below. You should just need a form with
a few controls to get this going (datagrid called "dgdEmployHist",
textbox called "txtCISurname", button called "btnLoadCtls", button
called "btnSaveXML")
'***CODE - see farther down for XML data and Schema and XML result of
Save***
Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Data
Public Class Form1
Inherits System.Windows.Forms.Form
Private dsRequest As New DataSet
Private xddRequest As XmlDataDocument
#Region " Windows Form Designer generated code "
'I REMOVED THIS TO SAVE SPACE
#End Region
Private Sub btnLoadCtls_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnLoadCtls.Click
Dim dtTemp As DataTable
Dim drwTemp As DataRow
Dim drlTemp As DataRelation
Dim ParentArr() As DataColumn
Dim ChildArr() As DataColumn
Dim i As Integer
Try
'LOAD A SCHEMA INTO THE EMPTY DATASET
dsRequest.ReadXmlSchema("C:\test.xsd")
Catch err As XmlSchemaException
Console.WriteLine("LineNumber = {0}", err.LineNumber)
Console.WriteLine("LinePosition = {0}", err.LinePosition)
Console.WriteLine("Message = {0}", err.Message)
Console.WriteLine("Source = {0}", err.Source)
Catch err As DataException
'Console.WriteLine("LineNumber = {0}", err.LineNumber)
'Console.WriteLine("LinePosition = {0}", err.LinePosition)
Console.WriteLine("Message = {0}", err.Message)
Console.WriteLine("Source = {0}", err.Source)
Catch err As Exception
Console.WriteLine("Message = {0}", err.Message)
Console.WriteLine("Source = {0}", err.Source)
End Try
'SYNC THE XMLDATADOCUMENT WITH THE DATASET
xddRequest = New XmlDataDocument(dsRequest)
'FILL THE DATADOCUMENT FROM THE XML DATA (FILLS THE DATASET AS
WELL BECAUSE THEY ARE NOW IN SYNC)
xddRequest.Load("c:\test.xml")
Debug.Write("DataTables" & vbCrLf)
For Each dtTemp In dsRequest.Tables
Debug.Write(vbTab & dtTemp.TableName() & ", recs=" &
dtTemp.Rows.Count & vbCrLf)
Next
Debug.Write("DataRelations" & vbCrLf)
For Each drlTemp In dsRequest.Relations
Debug.Write(vbTab & drlTemp.RelationName & ", nested=" &
drlTemp.Nested & vbCrLf)
Debug.Write(vbTab & "ParentColumns" & vbCrLf)
ParentArr = drlTemp.ParentColumns
For i = 0 To ParentArr.GetUpperBound(0)
Debug.Write(vbTab & vbTab & ParentArr(i).ColumnName &
vbCrLf)
Next i
Debug.Write(vbTab & "ChildColumns" & vbCrLf)
ChildArr = drlTemp.ChildColumns
For i = 0 To ChildArr.GetUpperBound(0)
Debug.Write(vbTab & vbTab & ChildArr(i).ColumnName &
vbCrLf)
Next i
Next
'Binding controls
Me.txtCISurname.DataBindings.Add _
(New Binding("Text", dsRequest.Tables("Individual"),
"Surname"))
Me.dgdEmployHist.DataSource =
dsRequest.Tables("Employment").DefaultView
End Sub
Private Sub btnSaveXML_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles btnSaveXML.Click
'Adding an Employment row
'Dim drwTest As DataRow =
dsRequest.Tables("Employment").NewRow
'drwTest("IndividualID") = "40992"
'drwTest("EmploymentID") = ""
'drwTest("JobTitle") = "Computer Programmer"
'dsRequest.Tables("Employment").Rows.Add(drwTest)
'removing an Employment Row
'dsRequest.Tables("Employment").Rows(0).Delete()
'Saving the changes to XML
dsRequest.AcceptChanges()
'Console.WriteLine(xddRequest.OuterXml())
xddRequest.Save("C:\saved.xml")
End Sub
End Class
'***XML DATA - test.xml
<?xml version="1.0"?>
<Request xmlns="http://tempuri.org/sample_database_request-11.xsd">
<RequestID>11</RequestID>
<ClearanceTypeID>2</ClearanceTypeID>
<Individual>
<RequestID>11</RequestID>
<IndividualID>40992</IndividualID>
<Surname>Jones</Surname>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>39216</EmploymentID>
<JobTitle>Painter</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73559</EmploymentID>
<JobTitle>Sweeper</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73564</EmploymentID>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73566</EmploymentID>
<JobTitle>Student</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73568</EmploymentID>
<JobTitle>Manager</JobTitle>
</Employment>
<CurrentAddress>
<IndividualID>40992</IndividualID>
<AddressID>7913</AddressID>
</CurrentAddress>
<BirthAddress>
<IndividualID>40992</IndividualID>
<AddressID>7914</AddressID>
</BirthAddress>
</Individual>
<RequestForm>
<RequestID>11</RequestID>
<FormID>1</FormID>
<USOID>12997</USOID>
</RequestForm>
<RequestForm>
<RequestID>11</RequestID>
<FormID>4</FormID>
<USOID>12997</USOID>
</RequestForm>
</Request>
'***XML Schema - test.xsd
<?xml version="1.0" ?>
<xs:schema id="NewDataSet"
targetNamespace="http://tempuri.org/sample_database_request-11.xsd"
xmlns:mstns="http://tempuri.org/sample_database_request-11.xsd"
xmlns="http://tempuri.org/sample_database_request-11.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="Request">
<xs:complexType>
<xs:sequence>
<xs:element name="RequestID" type="xs:string" minOccurs="0" />
<xs:element name="ClearanceTypeID" type="xs:string" minOccurs="0"
/>
<xs:element name="Individual" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="RequestID" type="xs:string" minOccurs="0" />
<xs:element name="IndividualID" type="xs:string" minOccurs="0"
/>
<xs:element name="Surname" type="xs:string" minOccurs="0" />
<xs:element name="Employment" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="IndividualID" type="xs:string"
minOccurs="0" />
<xs:element name="EmploymentID" type="xs:string"
minOccurs="0" />
<xs:element name="JobTitle" type="xs:string" minOccurs="0"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CurrentAddress" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="IndividualID" type="xs:string"
minOccurs="0" />
<xs:element name="AddressID" type="xs:string" minOccurs="0"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="BirthAddress" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="IndividualID" type="xs:string"
minOccurs="0" />
<xs:element name="AddressID" type="xs:string" minOccurs="0"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RequestForm" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="RequestID" type="xs:string" minOccurs="0" />
<xs:element name="FormID" type="xs:string" minOccurs="0" />
<xs:element name="USOID" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true"
msdata:EnforceConstraints="False">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Request" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
'***XML Result of Saving from synched XMLDataDocument - saved.xml
<?xml version="1.0"?>
<NewDataSet xmlns="http://tempuri.org/sample_database_request-11.xsd">
<Request xmlns="http://tempuri.org/sample_database_request-11.xsd">
<RequestID>11</RequestID>
<ClearanceTypeID>2</ClearanceTypeID>
<Individual>
<RequestID>11</RequestID>
<IndividualID>40992</IndividualID>
<Surname>Jones</Surname>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>39216</EmploymentID>
<JobTitle>Painter</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73559</EmploymentID>
<JobTitle>Sweeper</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73564</EmploymentID>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73566</EmploymentID>
<JobTitle>Student</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73568</EmploymentID>
<JobTitle>Manager</JobTitle>
</Employment>
<CurrentAddress>
<IndividualID>40992</IndividualID>
<AddressID>7913</AddressID>
</CurrentAddress>
<BirthAddress>
<IndividualID>40992</IndividualID>
<AddressID>7914</AddressID>
</BirthAddress>
</Individual>
<RequestForm>
<RequestID>11</RequestID>
<FormID>1</FormID>
<USOID>12997</USOID>
</RequestForm>
<RequestForm>
<RequestID>11</RequestID>
<FormID>4</FormID>
<USOID>12997</USOID>
</RequestForm>
</Request>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>1</EmploymentID>
<JobTitle>test</JobTitle>
</Employment>
</NewDataSet>
a Dataset. The XML data is fairly simple (see below). I load a
schema (using ReadXMLSchema) into the Dataset (as described in the MS
examples). Then I synch the dataset and the XMLDataDocument. Finally
the XML is loaded in to the XMLDataDocument. I then bind a textbox to
the "Surname" element and a datagrid to the "Employment" repeating
element
This is all working fine for me except one hitch. It seems that both
editing in the textbox or grid is fine. Also deleting a row from the
grid is fine as well. However 'inserting' a row into the Employment
grid (either manually or programatically - try adding one on the end
of the grid - you'll see) does not seem to place the new node into the
proper position in the XML hierarchy (it gets appended at the end of
the structure - just before the 'NewDatset' element). Note that I am
writing out the edited XML with the "Save" method for the
XMLDataDocument" object. I think there is something improper going on
in the data relations (as you can see I debugged them - they look
fine). Also note that I used the Schema Designer to make the XSD file
associated with this XML data. It just seems weird that editing and
deleting are resoved correctly within the hierarchy, but inserting is
not.
All the code and XML is found below. You should just need a form with
a few controls to get this going (datagrid called "dgdEmployHist",
textbox called "txtCISurname", button called "btnLoadCtls", button
called "btnSaveXML")
'***CODE - see farther down for XML data and Schema and XML result of
Save***
Imports System
Imports System.Xml
Imports System.Xml.Schema
Imports System.Data
Public Class Form1
Inherits System.Windows.Forms.Form
Private dsRequest As New DataSet
Private xddRequest As XmlDataDocument
#Region " Windows Form Designer generated code "
'I REMOVED THIS TO SAVE SPACE
#End Region
Private Sub btnLoadCtls_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnLoadCtls.Click
Dim dtTemp As DataTable
Dim drwTemp As DataRow
Dim drlTemp As DataRelation
Dim ParentArr() As DataColumn
Dim ChildArr() As DataColumn
Dim i As Integer
Try
'LOAD A SCHEMA INTO THE EMPTY DATASET
dsRequest.ReadXmlSchema("C:\test.xsd")
Catch err As XmlSchemaException
Console.WriteLine("LineNumber = {0}", err.LineNumber)
Console.WriteLine("LinePosition = {0}", err.LinePosition)
Console.WriteLine("Message = {0}", err.Message)
Console.WriteLine("Source = {0}", err.Source)
Catch err As DataException
'Console.WriteLine("LineNumber = {0}", err.LineNumber)
'Console.WriteLine("LinePosition = {0}", err.LinePosition)
Console.WriteLine("Message = {0}", err.Message)
Console.WriteLine("Source = {0}", err.Source)
Catch err As Exception
Console.WriteLine("Message = {0}", err.Message)
Console.WriteLine("Source = {0}", err.Source)
End Try
'SYNC THE XMLDATADOCUMENT WITH THE DATASET
xddRequest = New XmlDataDocument(dsRequest)
'FILL THE DATADOCUMENT FROM THE XML DATA (FILLS THE DATASET AS
WELL BECAUSE THEY ARE NOW IN SYNC)
xddRequest.Load("c:\test.xml")
Debug.Write("DataTables" & vbCrLf)
For Each dtTemp In dsRequest.Tables
Debug.Write(vbTab & dtTemp.TableName() & ", recs=" &
dtTemp.Rows.Count & vbCrLf)
Next
Debug.Write("DataRelations" & vbCrLf)
For Each drlTemp In dsRequest.Relations
Debug.Write(vbTab & drlTemp.RelationName & ", nested=" &
drlTemp.Nested & vbCrLf)
Debug.Write(vbTab & "ParentColumns" & vbCrLf)
ParentArr = drlTemp.ParentColumns
For i = 0 To ParentArr.GetUpperBound(0)
Debug.Write(vbTab & vbTab & ParentArr(i).ColumnName &
vbCrLf)
Next i
Debug.Write(vbTab & "ChildColumns" & vbCrLf)
ChildArr = drlTemp.ChildColumns
For i = 0 To ChildArr.GetUpperBound(0)
Debug.Write(vbTab & vbTab & ChildArr(i).ColumnName &
vbCrLf)
Next i
Next
'Binding controls
Me.txtCISurname.DataBindings.Add _
(New Binding("Text", dsRequest.Tables("Individual"),
"Surname"))
Me.dgdEmployHist.DataSource =
dsRequest.Tables("Employment").DefaultView
End Sub
Private Sub btnSaveXML_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles btnSaveXML.Click
'Adding an Employment row
'Dim drwTest As DataRow =
dsRequest.Tables("Employment").NewRow
'drwTest("IndividualID") = "40992"
'drwTest("EmploymentID") = ""
'drwTest("JobTitle") = "Computer Programmer"
'dsRequest.Tables("Employment").Rows.Add(drwTest)
'removing an Employment Row
'dsRequest.Tables("Employment").Rows(0).Delete()
'Saving the changes to XML
dsRequest.AcceptChanges()
'Console.WriteLine(xddRequest.OuterXml())
xddRequest.Save("C:\saved.xml")
End Sub
End Class
'***XML DATA - test.xml
<?xml version="1.0"?>
<Request xmlns="http://tempuri.org/sample_database_request-11.xsd">
<RequestID>11</RequestID>
<ClearanceTypeID>2</ClearanceTypeID>
<Individual>
<RequestID>11</RequestID>
<IndividualID>40992</IndividualID>
<Surname>Jones</Surname>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>39216</EmploymentID>
<JobTitle>Painter</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73559</EmploymentID>
<JobTitle>Sweeper</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73564</EmploymentID>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73566</EmploymentID>
<JobTitle>Student</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73568</EmploymentID>
<JobTitle>Manager</JobTitle>
</Employment>
<CurrentAddress>
<IndividualID>40992</IndividualID>
<AddressID>7913</AddressID>
</CurrentAddress>
<BirthAddress>
<IndividualID>40992</IndividualID>
<AddressID>7914</AddressID>
</BirthAddress>
</Individual>
<RequestForm>
<RequestID>11</RequestID>
<FormID>1</FormID>
<USOID>12997</USOID>
</RequestForm>
<RequestForm>
<RequestID>11</RequestID>
<FormID>4</FormID>
<USOID>12997</USOID>
</RequestForm>
</Request>
'***XML Schema - test.xsd
<?xml version="1.0" ?>
<xs:schema id="NewDataSet"
targetNamespace="http://tempuri.org/sample_database_request-11.xsd"
xmlns:mstns="http://tempuri.org/sample_database_request-11.xsd"
xmlns="http://tempuri.org/sample_database_request-11.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="Request">
<xs:complexType>
<xs:sequence>
<xs:element name="RequestID" type="xs:string" minOccurs="0" />
<xs:element name="ClearanceTypeID" type="xs:string" minOccurs="0"
/>
<xs:element name="Individual" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="RequestID" type="xs:string" minOccurs="0" />
<xs:element name="IndividualID" type="xs:string" minOccurs="0"
/>
<xs:element name="Surname" type="xs:string" minOccurs="0" />
<xs:element name="Employment" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="IndividualID" type="xs:string"
minOccurs="0" />
<xs:element name="EmploymentID" type="xs:string"
minOccurs="0" />
<xs:element name="JobTitle" type="xs:string" minOccurs="0"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CurrentAddress" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="IndividualID" type="xs:string"
minOccurs="0" />
<xs:element name="AddressID" type="xs:string" minOccurs="0"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="BirthAddress" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="IndividualID" type="xs:string"
minOccurs="0" />
<xs:element name="AddressID" type="xs:string" minOccurs="0"
/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RequestForm" minOccurs="0"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="RequestID" type="xs:string" minOccurs="0" />
<xs:element name="FormID" type="xs:string" minOccurs="0" />
<xs:element name="USOID" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true"
msdata:EnforceConstraints="False">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Request" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
'***XML Result of Saving from synched XMLDataDocument - saved.xml
<?xml version="1.0"?>
<NewDataSet xmlns="http://tempuri.org/sample_database_request-11.xsd">
<Request xmlns="http://tempuri.org/sample_database_request-11.xsd">
<RequestID>11</RequestID>
<ClearanceTypeID>2</ClearanceTypeID>
<Individual>
<RequestID>11</RequestID>
<IndividualID>40992</IndividualID>
<Surname>Jones</Surname>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>39216</EmploymentID>
<JobTitle>Painter</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73559</EmploymentID>
<JobTitle>Sweeper</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73564</EmploymentID>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73566</EmploymentID>
<JobTitle>Student</JobTitle>
</Employment>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>73568</EmploymentID>
<JobTitle>Manager</JobTitle>
</Employment>
<CurrentAddress>
<IndividualID>40992</IndividualID>
<AddressID>7913</AddressID>
</CurrentAddress>
<BirthAddress>
<IndividualID>40992</IndividualID>
<AddressID>7914</AddressID>
</BirthAddress>
</Individual>
<RequestForm>
<RequestID>11</RequestID>
<FormID>1</FormID>
<USOID>12997</USOID>
</RequestForm>
<RequestForm>
<RequestID>11</RequestID>
<FormID>4</FormID>
<USOID>12997</USOID>
</RequestForm>
</Request>
<Employment>
<IndividualID>40992</IndividualID>
<EmploymentID>1</EmploymentID>
<JobTitle>test</JobTitle>
</Employment>
</NewDataSet>