Search code examples
c#datatablestringtemplate

Output DataTable using StringTemplate


I'm trying to implement a method that will accept DataTable with StringTemplate and return string representation of data.

I found how to do this here and here, but it doesn't work for me.

Example code:

// Here can be any table with any number of columns.
var table = new DataTable();
table.Columns.Add("StrCol", typeof(string));
table.Columns.Add("IntCol", typeof(int));
table.Rows.Add(new object[] { "Row1String", 1 });
table.Rows.Add(new object[] { "Row2String", 2 });

var data = from dataRow in table.AsEnumerable()
           select dataRow;

var st = new StringTemplate("$items:{$it.StrCol$ $it.IntCol$}$");
st.SetAttribute("items", data);
Console.Write(st.ToString());

Result:

Class DataRow has no such attribute: StrCol in template context [anonymous anonymous]
Class DataRow has no such attribute: IntCol in template context [anonymous anonymous]
Class DataRow has no such attribute: StrCol in template context [anonymous anonymous]
Class DataRow has no such attribute: IntCol in template context [anonymous anonymous]

UPD:

I have to use Antlr3.StringTemplate.dll version 3.1.0 of StringTemplate. I decided to try on another version and downloaded Antlr3.StringTemplate.dll version 3.3.0. Everything works fine. So, is there any way to apply template on DataTable using old library?


Solution

  • The possible workaround to use string templates on DataTable is to convert rows to collection of dictionaries, so it will be possible to access rows cells by column names:

    var columns = table.Columns.Cast<DataColumn>().Select(col => col.ColumnName);
    var data = from DataRow row in table.Rows
               select columns.ToDictionary(col => col, col => row[col]);
    
    var st = new StringTemplate("$items:{$it.StrCol$ $it.IntCol$\n}$");
    st.SetAttribute("items", data);
    

    With newer version of StringTemplate library that works with DataTable:

    var st = new StringTemplate("$items:{$it.StrCol$ $it.IntCol$\n}$");
    st.SetAttribute("items", table.Rows);