In .NET 2.0 based projects, converting a data table into formatted XML requires using nested "for
" loops. In the current versions of .NET, we can use the capabilities of LINQ to XML to build efficient code. Below is a code snippet that I found in one of my projects that uses for
loops to convert data tables to formatted XML. The main objective of this code is to convert the 'ModelUpn
' table to XML by appending the data table returned by Custom.GetAttrLangByRecNoRevNo
as its sub nodes. The final output XML should look something like this:
="1.0"="UTF-8"
<string xmlns="http://xxxxx.xxxxxxxxx.xxxx/">
<SavedConfigXML>
<MODEL_UPN>
<OWN_DIV_ID>A80010</OWN_DIV_ID>
<OWN_PART_NO>L90LS </OWN_PART_NO>
<REC_NO>3</REC_NO>
<REVISION_NO>1</REVISION_NO>
<SECTION_PART_NO> </SECTION_PART_NO>
<ESTIMATE_NUM>0000000002</ESTIMATE_NUM>
<LABEL>
<OWN_DIV_ID>A80010</OWN_DIV_ID>
<OWN_PART_NO>L90LS </OWN_PART_NO>
<REC_NO>3</REC_NO>
<REVISION_NO>1</REVISION_NO>
<ATTR_SEQ>1</ATTR_SEQ>
<ATTR_NUM>94</ATTR_NUM>
</LABEL>
<LABEL>
<OWN_DIV_ID>A80010</OWN_DIV_ID>
<OWN_PART_NO>L90LS </OWN_PART_NO>
<REC_NO>3</REC_NO>
<REVISION_NO>1</REVISION_NO>
<ATTR_SEQ>3</ATTR_SEQ>
<ATTR_NUM>95</ATTR_NUM>
</LABEL>
</MODEL_UPN>
<MODEL_UPN>
<OWN_DIV_ID>A80010</OWN_DIV_ID>
<OWN_PART_NO>L90LS </OWN_PART_NO>
<REC_NO>4</REC_NO>
<REVISION_NO>1</REVISION_NO>
<SECTION_PART_NO>L90LS_INLET </SECTION_PART_NO>
<ESTIMATE_NUM>0000000002</ESTIMATE_NUM>
<LABEL>
<OWN_DIV_ID>A80010</OWN_DIV_ID>
<OWN_PART_NO>L90LS </OWN_PART_NO>
<REC_NO>4</REC_NO>
<REVISION_NO>1</REVISION_NO>
<ATTR_SEQ>1</ATTR_SEQ>
<ATTR_NUM>12</ATTR_NUM>
</LABEL>
<LABEL>
<OWN_DIV_ID>A80010</OWN_DIV_ID>
<OWN_PART_NO>L90LS </OWN_PART_NO>
<REC_NO>4</REC_NO>
<REVISION_NO>1</REVISION_NO>
<ATTR_SEQ>2</ATTR_SEQ>
<ATTR_NUM>13</ATTR_NUM>
</LABEL>
</MODEL_UPN>
</SavedConfigXML>
</string>
If you are using for
loops, then you have to loop through the data tables and use the XML libraries to create and appropriately place the parent and child nodes (see the code below).
public string ConvertDataTableToXml(ModelUpn modelupn)
{
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement(modelupn.TableName);
doc.AppendChild(root);
for (int k = 0; k < modelupn.Count; k++)
{
for (int j = 0; j < modelupn.Columns.Count; j++)
{
XmlElement elemdivid =
doc.CreateElement(modelupn.Columns[j].ToString().Trim());
elemdivid.InnerText = modelupn.Rows[k][j].ToString().Trim();
root.AppendChild(elemdivid);
}
DataTable dt = Custom.GetAttrLangByRecNoRevNo(modelupn[k].OWN_DIV_ID,
modelupn[k].OWN_PART_NO,
modelupn[k].REC_NO,
modelupn[k].REVISION_NO);
for (int i = 0; i < dt.Rows.Count; i++)
{
XmlElement elemattrlbl = doc.CreateElement(dt.TableName);
root.AppendChild(elemattrlbl);
for (int l = 0; l < dt.Columns.Count; l++)
{
XmlElement elemsubdiv =
doc.CreateElement(dt.Columns[l].ToString().Trim());
elemsubdiv.InnerText = dt.Rows[i][l].ToString().Trim();
elemattrlbl.AppendChild(elemsubdiv);
}
}
}
string xmlOut = doc.InnerXml;
return xmlOut;
}
Using LINQ to XML, C# code is not only legible, but also efficient. [DataTable].AsEnumerable
converts a data table into an enumerable. With proper casting to <datacolumn>
, the data table can be converted to XML using LINQ to XML.
public string FormatSavedConfigXML(ModelUpn modelupn)
{
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "true"),
new XElement("SavedConfigXML",
from model in modelupn.AsEnumerable()
select new XElement(modelupn.TableName,
from column in modelupn.Columns.Cast<DataColumn>()
select new XElement(column.ColumnName, model[column.ColumnName]),
new XElement(select new XElement("LABEL",
from lblcolumn in
Custom.GetModelAttrsWithLabel(
model["OWN_DIV_ID"].ToString(),
model["OWN_PART_NO"].ToString(),
Convert.ToInt32(model["REC_NO"]),
Convert.ToInt32(model["REVISION_NO"])).Columns.Cast<DataColumn>()
select new XElement(lblcolumn.ColumnName, label[lblcolumn.ColumnName]))))));
string xmlOut = doc.ToString(SaveOptions.None);
return xmlOut;
}
Do post your comments or suggestions to this post.