Vous êtes sur la page 1sur 6

Create Some Generic Way of XML Parsing

and Data Table Management

Introduction
The aim of this code snippet is to create a generic datatable where data table column order, display
name property can be managed.

Background
Assume we have two classes with different types of properties. We would like to create a generic
method for each class, that will be responsible for creating a data table, ordering data table column,
data table caption, parsing data from XML and finally, showing it into datagridview.

Using the Code


Step 1: Create a Class Where Property Names Must Be Exactly Like Tag
Name of XML Need to Be Parsed
Hide Copy Code
public class CustomerEnquire
{
[Display(Name = "Customer Number")]
[Column(Order = 1)]
public string CustNum { get; set; }

[Display(Name = "Title Code")]


[Column(Order = 0)]
public string TitleCode { get; set; }

[Display(Name = "First Name")]


[Column(Order = 2)]
public string FirstName { get; set; }

[Display(Name = "Customer Middle Name")]


[Column(Order = 3)]
public string CustMidName { get; set; }

[Column(Order = 4)]
public string LastName { get; set; }

[Column(Order = 5)]
[Display(Name = "Error Message")]
public string ErrorMessage { get; set; }
}

Step 2: Create a Function That Will Be Used for Datagrid Styling

Hide Shrink Copy Code

public class TempDataGridStyler


{
public TempDataGridStyler()
{
ColumnName = "";
ColumnCaption = "";
ColumnIndex = 0;
}
public string ColumnName { get; set; }
public string ColumnCaption { get; set; }

public int ColumnIndex { get; set; }


}

public static List<TempDataGridStyler> GenerateDataGridStyler<T>(this IList<T> data)


{
var stylerList = new List<TempDataGridStyler>();
DataColumn column;
PropertyDescriptorCollection props =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
var styler = new TempDataGridStyler();
PropertyDescriptor prop = props[i];
MemberInfo property = typeof(T).GetProperty(prop.Name);
column = table.Columns.Add(prop.Name, prop.PropertyType);
var displayName =
property.GetCustomAttribute(typeof(DisplayAttribute)) as
DisplayAttribute;
var columnOrder = property.GetCustomAttribute
(typeof(ColumnAttribute)) as ColumnAttribute;

if (columnOrder!=null)
{
styler.ColumnIndex = columnOrder.Order;
}
else
{
styler.ColumnIndex = i;
}
if (displayName != null)
{
column.Caption = displayName.Name;
styler.ColumnCaption = displayName.Name;
}
else
{
column.Caption = prop.Name;
styler.ColumnCaption = prop.Name;
}
styler.ColumnName = prop.Name;
stylerList.Add(styler);
}
return stylerList;
}

To call this function:

Hide Copy Code

var gridStyler = GenerateDataGridStyler(new List<CustomerEnquire>());

Step 3: Create a Function That Will Be Used for Data Table Column,
Caption Creation and Column Order Management

Hide Shrink Copy Code


public class TempSetOrdinal
{
public string ColumnName { get; set; }
public string ColumnCaption { get; set; }
public int ColumnOrder { get; set; }
public Type PropertyType { get; set; }
}

public static DataTable GenerateDataTableDynamicColumn<T>


(this IList<T> data, string tableName)
{
var lstColumns = new List<TempSetOrdinal>();
DataColumn column;
PropertyDescriptorCollection props =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
table.TableName = tableName;

for (int i = 0; i < props.Count; i++)


{
var columnProp = new TempSetOrdinal();
PropertyDescriptor prop = props[i];
MemberInfo property = typeof(T).GetProperty(prop.Name);
var displayName = property.GetCustomAttribute
(typeof(DisplayAttribute)) as DisplayAttribute;
var columnOrder = property.GetCustomAttribute
(typeof(ColumnAttribute)) as ColumnAttribute;

columnProp.ColumnName = prop.Name;
columnProp.ColumnCaption = displayName == null ? prop.Name :
displayName.Name;
columnProp.ColumnOrder = columnOrder == null ? i : columnOrder.Order;
columnProp.PropertyType = prop.PropertyType;
lstColumns.Add(columnProp);
}

var col = lstColumns.OrderBy(p => p.ColumnOrder);

foreach (var item in lstColumns.OrderBy(p=>p.ColumnOrder))


{
column = table.Columns.Add(item.ColumnName, item.PropertyType);
column.Caption = item.ColumnCaption;
column.SetOrdinal(item.ColumnOrder);
}

return table;
}

public static DataTable GenerateDataTableDynamicCaption<T>


(this IList<T> data, string tableName)
{
var lstColumns = new List<TempSetOrdinal>();
DataColumn column;
PropertyDescriptorCollection props =
TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
table.TableName = tableName;

for (int i = 0; i < props.Count; i++)


{
var columnProp = new TempSetOrdinal();
PropertyDescriptor prop = props[i];
MemberInfo property = typeof(T).GetProperty(prop.Name);
var displayName = property.GetCustomAttribute
(typeof(DisplayAttribute)) as DisplayAttribute;
var columnOrder = property.GetCustomAttribute
(typeof(ColumnAttribute)) as ColumnAttribute;

columnProp.ColumnName = prop.Name;
columnProp.ColumnCaption = displayName == null ? prop.Name :
displayName.Name;
columnProp.ColumnOrder = columnOrder == null ? i : columnOrder.Order;
columnProp.PropertyType = prop.PropertyType;
lstColumns.Add(columnProp);
}

foreach (var item in lstColumns.OrderBy(p => p.ColumnOrder))


{
column = table.Columns.Add(item.ColumnCaption, item.PropertyType);
column.Caption = item.ColumnCaption;
column.SetOrdinal(item.ColumnOrder);
}
return table;
}

To call functions:

Hide Copy Code


var dtColumn = GenerateDataTableDynamicColumn(new List<CustomerEnquire>(),
"soapresponse");
var dtCaption = GenerateDataTableDynamicCaption(new List<CustomerEnquire>(),
"soapresponse");

Step 4: Create a Function That Will Be Used for Reading Data From XML,
Write It Into Datatable

Hide Shrink Copy Code

public class TempAddedColumn


{
public string ColumnName { get; set; }
}

public static DataTable GenerateDataRows(XmlNodeList xChildNodelst,


DataTable dt, string xmlValue, DataTable dtCaption, List<TempDataGridStyler>
gridStyler)
{
var dtList = new List<TempAddedColumn>();

string[] columnNames = dt.Columns.Cast<DataColumn>()


.Select(x => x.ColumnName)
.ToArray();

foreach (XmlNode xnl in xChildNodelst)


{
var captionName = string.Empty;
dtCaption.Rows.Add();
foreach (var item in columnNames)
{
if (!dtList.Where(p => p.ColumnName == item.Trim()).Any())
{
if (gridStyler.Where(p => p.ColumnName == item).Any())
{
captionName = gridStyler.Where
(p => p.ColumnName ==
item).FirstOrDefault().ColumnCaption;
}
else
{
captionName = item;
}
var obj = new TempAddedColumn();
dtList.Add(obj);
var xmlNode = xmlValue + item;
var value = StringValueChecker(xnl[xmlNode]);
dtCaption.Rows[dtCaption.Rows.Count - 1][captionName] =
StringValueChecker(xnl[xmlNode]);
}
}
}
return dtCaption;
}

To call this method:

Hide Copy Code

dtCaption = GenerateDataRows(xChildNodelst, dtColumn, "ns2:", dtCaption, gridStyler);

Step 5: Show Data Table in Data Grid View


Hide Copy Code

gdvData.DataSource = null;
gdvData.DataSource = dtCaption;
gdvData.DataBind();

Points of Interest
 To create some generic way of XML parsing, Data table management