Problem:
In your comments, indicate that you do not know how to add internal elements that will create attributes in the resulting XML. The rest of your code works fine except for this bit:
//I am unable to write the next line xInnerElt[j] = new XElement(InnerTagName,new XAttribute((XName)ColumnName,rows Item arry)),
Decision
The unacceptable part you want is to skip the columns located on the DataTable , and then access the column values ββin the row. This is because the DataRow object does not have column name information.
Therefore, to get the value from the current column, you need another inner loop through the DataTable.Columns collection, and then use the dt.Rows[j][column] element for the DataRow column dt.Rows[j][column] .
It looks like this:
foreach (var column in dt[i].Columns) { xInnerElt[j].Add( new XAttribute( (column as DataColumn).ColumnName, dt[i].Rows[j][(column as DataColumn)].ToString() ) ); }
My test with code:
using System; using System.Collections.Generic; using System.Data; using System.Xml.Linq; namespace XElemFromDT { class Program { static void Main(string[] args) { Dictionary<string, string> htAtributNameForTable = new Dictionary<string, string>() { { "Software", "software_entry" }, { "ApplicationConfigurations", "config" } }; DataTable dt1 = new DataTable(); dt1.TableName = "Software"; dt1.Columns.Add("name", typeof(string)); dt1.Columns.Add("path", typeof(string)); dt1.Rows.Add("Adobe Acrobat X Standard", @"Applications\Acrobat\Acrobat XStandard\AcroStan.msi"); dt1.Rows.Add("Adobe Photoshop", @"Applications\Photoshop\Photoshop.msi"); DataTable dt2 = new DataTable(); dt2.TableName = "ApplicationConfigurations"; dt2.Columns.Add("name", typeof(string)); dt2.Columns.Add("value", typeof(string)); dt2.Rows.Add("someName", "someValue"); dt2.Rows.Add("someOtherName", "someOtherValue"); DataTable[] dt = new DataTable[] { dt1, dt2 }; XDocument xDoc = new XDocument(new XElement("Root")); for (int i = 0; i < dt.Length; i++) //for every table { XName TableName = dt[i].TableName; //table name. XElement[] xInnerElt = new XElement[dt[i].Rows.Count]; //for n rows inside one table for (int j = 0; j < dt[i].Rows.Count; j++) //loop each tag inside the table { XName InnerTagName = htAtributNameForTable[dt[i].TableName].ToString(); //tag name form hash table. ie, software_entry //I am unable to write the next line xInnerElt[j] = new XElement(InnerTagName); foreach (var column in dt[i].Columns) { xInnerElt[j].Add( new XAttribute( (column as DataColumn).ColumnName, dt[i].Rows[j][(column as DataColumn)].ToString() ) ); } } XElement xElt = new XElement(TableName, xInnerElt); //one table aded to tag. xDoc.Root.Add(xElt); } Console.WriteLine(xDoc.ToString()); Console.ReadKey(); } } }
Bonus - because I had to try this
Here you can do it completely with LINQ: (using the same test data as my previous example)
DataTable[] dt = new DataTable[] { dt1, dt2 }; XDocument xDoc = new XDocument(new XElement("Root")); Func<DataTable, DataRow, IEnumerable<XAttribute>> getAttributes = (t, r) => t.Columns.OfType<DataColumn>().Select(c => new XAttribute(c.ColumnName, r[c].ToString())); Func<DataTable, IEnumerable<XElement>> getElements = t => t.Rows.OfType<DataRow>().Select(r => new XElement(htAtributNameForTable[t.TableName], getAttributes(t, r))); Func<DataTable[], IEnumerable<XElement>> getTables = dtc => dtc.AsEnumerable().Select(t => new XElement(t.TableName, getElements(t))); xDoc.Root.Add(getTables(dt));