Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Data Tables to Formatted XML (for loops vs. LINQ to XML)

5.00/5 (1 vote)
2 Oct 2011CPOL 12.3K  
Using LINQ to XML to convert datatables to formatted XML.

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:


XML
<?xml version="1.0" encoding="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).


C#
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.


C#
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)