I want to create nested XML from DataTable without loop.
DataTable: Employee
I had tried the following code snippet
DataSet ds=new DataSet ("EmployeeDetails");
DataTable dtConvert = datatable to be converted
ds.Tables.Add(dtConvert);
ds.WriteXml("sample.txt");
and got the XML which looks like,
<EmployeeDetails>
<Employee>
<name>John</name>
<city>chennai</city>
<state>Tamilnadu</state>
<country>India</country>
</Employee>
<Employee>
<name>David</name>
<city>Bangalore</city>
<state>Karnataka</state>
<country>India</country>
</Employee>
</EmployeeDetails>
But the XML format I want is
<EmployeeDetails>
<Employee>
<name>John</name>
<address>
<city>chennai</city>
<state>Tamilnadu</state>
<country>India</country>
</address>
</Employee>
<Employee>
<name>David</name>
<address>
<city>Bangalore</city>
<state>Karnataka</state>
<country>India</country>
</address>
</Employee>
</EmployeeDetails>
Can anyone please guide me to do this in a best way?
DataSet ds = new DataSet("EmployeeList");
//create table address
DataTable address = new DataTable("Address");
DataColumn column;
//add column id
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "ID";
address.Columns.Add(column);
//address.PrimaryKey = new DataColumn[1] { column };
//add column City
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "City";
address.Columns.Add(column);
//add column State
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "State";
address.Columns.Add(column);
//add column Country
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Country";
address.Columns.Add(column);
ds.Tables.Add(address); //add table address to dataset
//create table employee
DataTable employee = new DataTable("Employee");
//add column ID
column = new DataColumn();
column.DataType = System.Type.GetType("System.Int32");
column.ColumnName = "ID";
employee.Columns.Add(column);
employee.PrimaryKey = new DataColumn[1] { column };
//add column Name
column = new DataColumn();
column.DataType = System.Type.GetType("System.String");
column.ColumnName = "Name";
employee.Columns.Add(column);
//add column Address
//column = new DataColumn();
//column.DataType = System.Type.GetType("System.Int32");
//column.ColumnName = "Address";
//employee.Columns.Add(column);
ds.Tables.Add(employee); //add table employee to dataset
//set foreign key constraint
//ForeignKeyConstraint fk = new ForeignKeyConstraint("AddressFK",
//ds.Tables["Address"].Columns["ID"], ds.Tables["Employee"].Columns["Address"]);
//fk.DeleteRule = Rule.None;
//ds.Tables["Employee"].Constraints.Add(fk);
//
// fill data to data set
//
DataRow row;
row = address.NewRow();
row["ID"] = 1;
row["City"] = "test";
row["State"] = "test";
row["Country"] = "test";
address.Rows.Add(row);
row = employee.NewRow();
row["Name"] = "abc";
row["ID"] = 1;
//row["Address"] = 1;
employee.Rows.Add(row);
DataRelation relation = ds.Relations.Add("relation", ds.Tables["Employee"].Columns["ID"], ds.Tables["Address"].Columns["ID"]);
relation.Nested = true;
ds.WriteXml("test.txt"); //create xml from dataset
What I'm trying to do here is creating 2 tables Employee
and Address
. Address
has 4 columns ID
- foreign key that refer to Employee
primary key, State
, City
, Country
. Employee
has 2 columns Name
, ID
- primary key. Then add those tables to dataset ds
. Finally, create xml from ds
.
P/S: I write this in pure text (without using IDE because this computer doesn't has any IDE :(, so if any error on typo or syntax, please let me know)
UPDATE I updated the code, now the result XML will look like this:
<?xml version="1.0" standalone="yes"?>
<EmployeeList>
<Employee>
<ID>1</ID>
<Name>abc</Name>
<Address>
<ID>1</ID>
<City>test</City>
<State>test</State>
<Country>test</Country>
</Address>
</Employee>
</EmployeeList>
I made a mistake with the relationship from last time, it should be a foreign key in address
that refer to employee
primary key (in this case, I user column ID
)
UPDATE2 to exclude ID from Address
, add this line right before you call ds.WriteXML("test.xml")
ds.Tables["Address"].Columns["ID"].ColumnMapping = MappingType.Hidden;
You can also add following line to exclude ID from employee as well:
ds.Tables["Employee"].Columns["ID"].ColumnMapping = MappingType.Hidden;
The main problem you have is that you're taking 1 DataTable and trying to break it into 2 Related DataTables. The best method would be to break out your table so you have an Employee Table and an Address Table, have those related via EmployeeId or something.
Then, you pull the information into two different tables, relate, and nest them accordingly:
DataSet empList = new DataSet("EmployeeDetails");
DataTable employee = Employees;
DataTable address = Addresses;
empList.Add(employee);
empList.Add(address);
DataRelation relEmpAdd = new DataRelation
(
"relEmpAdd"
,employee.Columns["Id"]
,address.Columns["EmployeeId"]
);
relEmpAdd.Nested = true;
ds.Relations.Add(relEmpAdd);