I think this can be done using recursive LINQ, but I still need to figure out how to write it correctly, so here is a solution with a recursive method:
First, you declare a method (I searched by Name , but you can also do this with Id ):
public static IEnumerable<XElement> BuildXML(string Parent, DataTable dt) { string filter = string.Format("[Parent] = '{0}'", Parent); return from x in dt.Select(filter) select new XElement("Person", new XAttribute("Name", x["Child"]), new XAttribute("User_Id", x["Reporting_To_UserId"]), BuildXML(x["Child"].ToString(), dt) ); }
Then you call it with the parent element (I added the top line, otherwise the request will be more complex):
var dt = new DataTable(); dt.Columns.AddRange(new[] { new DataColumn("Parent"), new DataColumn("UserId"), new DataColumn("Child"), new DataColumn("Reporting_To_UserId"), new DataColumn("Depth"), new DataColumn("id") }); dt.Rows.Add(new object[] { "", 0, "Aditya", 13, 0, 12 }); dt.Rows.Add(new object[] {"Aditya", 13, "Abhishek", 4, 0, 13}); dt.Rows.Add(new object[] { "Abhishek", 4, "Saurabh", 6, 1, 16 }); dt.Rows.Add(new object[] { "Abhishek", 13, "Mohinder", 8, 1, 17 }); dt.Rows.Add(new object[] { "Mohinder", 8, "Mohammad", 14, 2, 18 }); dt.Rows.Add(new object[] { "Saurabh", 6, "Rahul", 1, 2, 11 }); dt.Rows.Add(new object[] { "Saurabh", 6, "Amitesh", 5, 2, 12 }); var result = BuildXML("", dt);
You now have an IEnumerable<XElement> to turn it into a string, you can do the following:
var xml = result. Select(e => e.ToString()). Aggregate((current, next) => current + next);