convert data set to xml string - c#

what i am trying to do is converting a dataset to an xml string. where t is returning me the output which contains the datasetname with datatable name . just i want to remove the datatable name and want to bind with only dataset node tag name. what should i do. here is my code.
if (sID > 0)
{
String retXml = String.Empty;
DataSet ds = new DataSet();
DataTable dtpdfAndEmailInfo = new DataTable("pdfandemailinfo");
DataRow dr = dtpdfAndEmailInfo.NewRow();
dtpdfAndEmailInfo.Clear();
dtpdfAndEmailInfo.Columns.Add("mailFrom", typeof(string));
dtpdfAndEmailInfo.Columns.Add("mailTo", typeof(string));
dtpdfAndEmailInfo.Columns.Add("mailCC", typeof(string));
dtpdfAndEmailInfo.Columns.Add("mailBCC", typeof(string));
dtpdfAndEmailInfo.Columns.Add("mailSubject", typeof(string));
dtpdfAndEmailInfo.Columns.Add("salesorderpdfurl", typeof(string));
ds.Tables.Add(dtpdfAndEmailInfo);
dtpdfAndEmailInfo.Rows.Add(dr);
String fileDirectory="D:\\po\\Sandbox\\po\\BOID_858_ORGID_571\\SalesOrderPdf\\" ;
String FileName ="BOID_858_SOID_151382.pdf";
for (int i = 0; i <= ds.Tables[0].Rows.Count - 1; i++)
{
ds.Tables[0].Rows[i]["mailFrom"] = "someemailid#yopmail.com";
ds.Tables[0].Rows[i]["mailTo"] = "someemailid1#yopmail.com";
ds.Tables[0].Rows[i]["mailCC"] = "someemailid2#yopmail.com";
ds.Tables[0].Rows[i]["mailSubject"] = "Test";
if (System.IO.File.Exists(Path.Combine(fileDirectory, FileName)))
{
ds.Tables[0].Rows[i]["SalesOrderPdfURL"] = Path.Combine(fileDirectory, FileName);
}
else
{
ds.Tables[0].Rows[i]["SalesOrderPdfURL"] = "";
}
}
Cmd.ResponseStatus.RowCount = ds.Tables[0].Rows.Count;
retXml = Util.GetXmlList(ds, "salesorderPdfAndEmailInfo", "pdfandemailinfos");
}
public static string GetXmlList(DataSet ds, String rootNode, String itemNode)
{
return GetXmlList(ds, rootNode, #"cls=""dataArray""", itemNode, #"cls=""dataItem""");
}
public static string GetXmlList(DataSet ds, String rootNode, String rootAttribute, String itemNode, String itemAttribute)
{
String rootNodeStartTag = String.Format("<{0} {1}>", rootNode, rootAttribute);
String rootNodeEndTag = String.Format("</{0}>", rootNode);
String nodeStartTag = String.Format("<{0} {1}>", itemNode, itemAttribute);
String nodeEndTag = String.Format("</{0}>", itemNode);
string retXML = ds.GetXml().Replace("<NewDataSet>", rootNodeStartTag).Replace("<Table>", nodeStartTag).Replace("</NewDataSet>", rootNodeEndTag).Replace("</Table>", nodeEndTag);
return HttpUtility.HtmlDecode(retXML);
}
and here is my response
"salesorderPdfAndEmailInfo": {
"pdfandemailinfo": {
"mailFrom": "someemailid#yopmail.com",
"mailTo": "someemailid1#yopmail.com",
"mailCC": "someemailid2#yopmail.com",
"mailSubject": "Test",
"salesorderpdfurl": "http://localhost/por/D:\\po\\Sandbox\\po\\BOID_858_ORGID_571\\SalesOrderPdf\\BOID_858_SOID_151382.pdf"
}
}
what response i want should be like remove the datatable node tag name.any help will be apprecited.
response should be like this..
"salesorderPdfAndEmailInfo": {
"mailFrom": "someemailid#yopmail.com",
"mailTo": "someemailid1#yopmail.com",
"mailCC": "someemailid2#yopmail.com",
"mailSubject": "Test",
"salesorderpdfurl": "http://localhost/por/D:\\po\\Sandbox\\po\\BOID_858_ORGID_571\\SalesOrderPdf\\BOID_858_SOID_151382.pdf"
}

Related

C# Newtonsoft JSON - Deserializing DataTable with nested object

I have the following JSON which needs to be deserialized.
{
"$type":"Lib.TableModel, Lib",
"DataTable":[
{
"Column1":"1",
"Column2":{
"$type":"Lib.RelationCellValue, Lib",
"CellName":"C1",
"FileName":"test1.txt"
},
"Column3":{
"$type":"Lib.RelationCellValue, Lib",
"CellName":"C2",
"FileName":"test2.txt"
}
}
],
"Name":"table1"
}
As the values for Column2 and Column3 are objects, Newtonsoft throws an exception
"Unexpected JSON token when reading DataTable: StartObject"
although the object is annotated with type information.
I'm deserializing like this:
JsonSerializer serializer = new JsonSerializer
{
TypeNameHandling = TypeNameHandling.All,
NullValueHandling = NullValueHandling.Ignore
};
try
{
using (StreamReader sr = new StreamReader(path))
using (JsonReader reader = new JsonTextReader(sr))
{
model = serializer.Deserialize<T>(reader);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException.ToString());
}
How can I provide a custom type converter for the Newtonsoft DataTable converter (or fix the issue)?
Edit: The TableModel is just a class with a DataTable property.
public class TableModel
{
private DataTable dataTable;
public DataTable DataTable
{
get => dataTable;
set
{
dataTable = value;
RaisePropertyChanged("DataTable");
}
}
}
The items in the DataTable are RelationCellValues:
public class RelationCellValue
{
public string CellName { get; set; }
public string FileName { get; set; }
}
Edit2: The number of columns in the DataTable is dynamic. Test code for generating a sample table:
public void LoadData()
{
dataTable = new DataTable();
DataColumn column;
column = new DataColumn("Column1");
column.DataType = typeof(string);
dataTable.Columns.Add(column);
column = new DataColumn("Column2");
column.DataType = typeof(RelationCellValue);
dataTable.Columns.Add(column);
column = new DataColumn("Column3");
column.DataType = typeof(RelationCellValue);
dataTable.Columns.Add(column);
// Header row
var row = dataTable.NewRow();
dataTable.Rows.Add(row);
//First row
row = dataTable.NewRow();
LoadCellValues(row, 1);
dataTable.Rows.Add(row);
//Second row
row = dataTable.NewRow();
LoadCellValues(row, 2);
dataTable.Rows.Add(row);
//Third row
row = dataTable.NewRow();
LoadCellValues(row, 3);
dataTable.Rows.Add(row);
}
public void LoadCellValues(DataRow dataRow, int ordinalNumber)
{
dataRow[0] = ordinalNumber.ToString();
dataRow[1] = new RelationCellValue() { CellName = "First Cell", FileName = "test.txt" };
dataRow[2] = new RelationCellValue() { CellName = "Second Cell", FileName = "test.txt" }; ;
}

CSV Parse out object c#

I need some help with parsing out a CSV we get it like this
OrderNumber,LineNumber,CustomerNumber,CustomerName,AddressLine1,AddressLine2,AddressLine3,AddressLine4,AddressLine5,PostCode,ProductCode,ProductName,Ordered,Left,Picked
we can have multiple lines for an order so we would get
order Number
CustomerNumber
CustomerName
AddressLine1
AddressLine2
AddressLine3
AddressLine4
AddressLine5
PostCode
matching multiple times I need a way of parsing this out to be this structure
<orderDespatchRequest>
<despatchDetails>
<clientCustomerId>CustomerNumber</clientCustomerId>
<clientOrderNumber>OrderNumber</clientOrderNumber>
<dateDespatch>2015-07-01T00:00:00</dateDespatch>
<despatchedDetail>
<orderDespatchDetail>
<lineNumber>LineNumber</lineNumber>
<productCode>ProductCode</productCode>
<productName>ProductName</productName>
<quantity>Picked</quantity>
</orderDespatchDetail>
</despatchedDetail>
</despatchDetails>
</orderDespatchRequest>
Hope someone can Help?
This is what I have got so far
public bool ExtractCSV(string file)
{
#region set up new dataTable
dt = new DataTable("Header");
dt.Columns.Add("OrderNumber", typeof(string));
dt.Columns.Add("Company", typeof(string));
dt.Columns.Add("AddressLine1", typeof(string));
dt.Columns.Add("AddressLine2", typeof(string));
dt.Columns.Add("AddressLine3", typeof(string));
dt.Columns.Add("AddressLine4", typeof(string));
dt.Columns.Add("AddressLine5", typeof(string));
dt.Columns.Add("PostCode", typeof(string));
detailTable = new DataTable("Details");
detailTable.Columns.Add("OrderNumber", typeof(string));
detailTable.Columns.Add("LineNumber", typeof(int));
detailTable.Columns.Add("ProductCode", typeof(string));
detailTable.Columns.Add("ProductName", typeof(string));
detailTable.Columns.Add("OrderQty", typeof(int));
detailTable.Columns.Add("OutstandingQty", typeof(int));
detailTable.Columns.Add("DespatchedQty", typeof(string));
detailTable.PrimaryKey = new DataColumn[] { detailTable.Columns["OrderNumber"] };
#endregion
#region Fill the table
// read in the csv file
string[] csvRows = File.ReadAllLines(file);
string[] fields = null;
foreach (string csvRow in csvRows)
{
fields = csvRow.Split(',');
string orderNumber = fields[0].ToString();
string customerNumber = fields[2].ToString();
string Company = fields[3].ToString();
string AddressLine1 = fields[4].ToString();
string AddressLine2 = fields[5].ToString();
string AddressLine3 = fields[6].ToString();
string AddressLine4 = fields[7].ToString();
string AddressLine5 = fields[8].ToString();
string PostCode = fields[9].ToString();
int LineNumber = Convert.ToInt32(fields[1]);
string ProductCode = fields[10].ToString();
string ProductName = fields[11].ToString();
int OrderQty = Convert.ToInt32(fields[12]);
int OutstandingQty = Convert.ToInt32(fields[13]);
int DespatchedQty = Convert.ToInt32(fields[14]);
dt.Rows.Add(orderNumber, Company, AddressLine1, AddressLine2, AddressLine3, AddressLine4, AddressLine5,PostCode);
detailTable.Rows.Add(orderNumber, ProductCode, ProductName, OrderQty, OutstandingQty, DespatchedQty);
}
#endregion
var query = from row in detailTable.AsEnumerable()
group row by row.Field<string>("OrderNumber") into grp
select new DataClass()
{
OrderNumber = grp.Key,
Details = grp
};
OrderDespatchDetail detail = new OrderDespatchDetail();
DespatchDetails despatchDetail = new DespatchDetails();
string orderNo = string.Empty;
string custNo = string.Empty;
foreach (DataRow item in query)
{
DataRow found = dt.Rows.Find(item.Field<string>("OrderNumber"));
if (orderNo != found.Field<string>("OrderNumber"))
{
}
detail.LineNumber = item.Field<int>("LineNumber");
detail.ProductCode = item.Field<string>("ProductCode");
detail.ProductName = item.Field<string>("ProductName");
detail.Quantity = item.Field<int>("");
}
OrderDespatchRequest request = new OrderDespatchRequest();
request.despatchDetails = despatchDetail;
return SendOrderDespatch(request);
}
Could be well off the path with it.
Regards
Aidan
As an example the following should get you started.
Read the CSV File
var rows = (from row in File.ReadAllLines("Test.csv")
let item = row.Split(',')
select new
{
OrderNumber = item[0],
LineNumber = item[1],
CustomerID = item[2],
Company = item[3],
AddressLine1 = item[4],
AddressLine2 = item[5],
AddressLine3 = item[6],
AddressLine4 = item[7],
AddressLine5 = item[8],
PostCode = item[9],
ProductCode = item[10].ToString(),
ProductName = item[11].ToString(),
OrderQty = item[12],
OutstandingQty = item[13],
DespatchedQty = item[14]
}).ToList();
Group the data per order into a dynamic type.
var orders = from p in rows
group p by new { OrderNumber = p.OrderNumber, CustomerID = p.CustomerID } into g
select new { OrderNumber = g.Key.OrderNumber, CustomerID = g.Key.CustomerID, OrderLines = g.ToList() };
Create the XML file (please note the output xml will not match your exact requirement, but this example should get you going).
var xEle = new XElement("Orders",
from order in orders
select new XElement("Order",
new XAttribute("OrderNumber", order.OrderNumber),
new XElement("CustomerId", order.CustomerID)
, from line in order.OrderLines
select new XElement("Line", new XAttribute("ProductCode", line.ProductCode),
new XElement("OrderQty", line.OrderQty))));
xEle.Save("orders.xml");
Console.WriteLine("Converted to XML");

Convert datatable into XML

I convert XML into datatable and now want to convert data table into XML again.
I have database in which four XML's are there and have to change that text xml
public ActionResult getChangeContent(string arg, string content)
{
char[] a = { ':' };
string[] id = arg.Split(a);
decimal tid = Convert.ToDecimal(id[0]);
decimal jid = Convert.ToDecimal(id[1]);
string groupname = id[2];
var gp = (from Trans_Mast in r2ge.Transcription_Master where Trans_Mast.Transcription_Id == tid && Trans_Mast.Entity_Id == jid select Trans_Mast).Distinct();
foreach (var g in gp)
{
DataSet ds = new DataSet();
ds.ReadXml(new XmlTextReader(new StringReader(g.Text_xml)));
DataTable text = ds.Tables[0];
for (int i = 0; i < text.Rows.Count; i++)
{
if (text.Rows[i]["group"].Equals(groupname))
{
text.Rows[i]["Text_Text"] = content;
}
text.AcceptChanges();
}
ConvertDatatableToXML(text);
}
return View();
}
public string ConvertDatatableToXML(DataTable dtTemp)
{
MemoryStream str = new MemoryStream();
dtTemp.WriteXml(str, true);
str.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(str);
string xmlstr;
xmlstr = sr.ReadToEnd();
return (xmlstr);
}
Data set is changed but there is no affect on XML.. any suggestion please..
use this piece of code :
private static string ConvertDataTableToXML(DataTable dtBuildSQL)
{
DataSet dsBuildSQL = new DataSet();
StringBuilder sbSQL;
StringWriter swSQL;
string XMLformat;
sbSQL = new StringBuilder();
swSQL = new StringWriter(sbSQL);
dsBuildSQL.Merge(dtBuildSQL, true, MissingSchemaAction.AddWithKey);
dsBuildSQL.Tables[0].TableName = “Table”;
foreach (DataColumn col in dsBuildSQL.Tables[0].Columns)
{
col.ColumnMapping = MappingType.Attribute;
}
dsBuildSQL.WriteXml(swSQL, XmlWriteMode.WriteSchema);
XMLformat = sbSQL.ToString();
return XMLformat;
}

C# function nested within a class method

I'm trying to implement a function within a Class method and I am somewhat new to C#.
Basically, I have a method that iterates through row in a database and sets values to variables. Then, if a document has been created already it updates the document, if not it creates the document. I'm trying to factor out some of the code and I don't know where to put it as it still needs a reference to my variables. I would like to factor out the repeated items in the if else statement.
private void SyncKinases()
{
DataSet ds = new DataSet();
ds = gn.ExecuteQuery("dx.kinasedatasheet.selectstagingkinases", null);
TreeProvider tp = new TreeProvider(ui);
VersionManager vm = new VersionManager(tp);
TreeNode node;
WorkflowManager wm = new WorkflowManager(tp);
if (ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
string className = "dx.kinasedatasheet";
string title = dr["Title"].ToString();
string technologyPlatform = dr["TechnologyPlatform"].ToString();
string ambitGeneSymbol = dr["AmbitGeneSymbol"].ToString();
string targetDescription = dr["TargetDescription"].ToString();
string entrezGeneSymbol = dr["EntrezGeneSymbol"].ToString();
int entrezGeneID = int.Parse(dr["EntrezGeneID"].ToString());
string aliases = dr["Aliases"].ToString();
string kinaseGroup = dr["KinaseGroup"].ToString();
string species = dr["Species"].ToString();
string accessionNumber = dr["AccessionNumber"].ToString();
string kinaseConstruct = dr["KinaseConstruct"].ToString();
string kinaseForm = dr["KinaseForm"].ToString();
string expressionSystem = dr["ExpressionSystem"].ToString();
double avgZValue = 0;
if (!(dr["AverageZValue"] is DBNull))
{
avgZValue = double.Parse(dr["AverageZValue"].ToString());
}
string panel = dr["Panel"].ToString();
string compoundsKds = dr["CompoundsKds"].ToString();
string mutationRelevance = dr["MutationRelevance"].ToString();
string mutationReferences = dr["MutationReferences"].ToString();
string kinaseAliasPath = "/Kinase-Data-Sheets";
if (!(dr["NodeID"] is System.DBNull))
{
node = tp.SelectSingleNode(int.Parse(dr["NodeID"].ToString()));
vm.CheckOut(node);
node.DocumentName = ambitGeneSymbol;
node.NodeName = ambitGeneSymbol;
node.SetValue("Title", title);
node.SetValue("TechnologyPlatform", technologyPlatform);
node.SetValue("AmbitGeneSymbol", ambitGeneSymbol);
node.SetValue("TargetDescription", targetDescription);
node.SetValue("EntrezGeneSymbol", entrezGeneSymbol);
node.SetValue("EntrezGeneID", entrezGeneID);
node.SetValue("Aliases", aliases);
node.SetValue("KinaseGroup", kinaseGroup);
node.SetValue("Species", species);
node.SetValue("AccessionNumber", accessionNumber);
node.SetValue("KinaseConstruct", kinaseConstruct);
node.SetValue("KinaseForm", kinaseForm);
node.SetValue("ExpressionSystem", expressionSystem);
if (!(dr["AverageZValue"] is DBNull))
{
node.SetValue("AverageZValue", avgZValue);
}
node.SetValue("Panel", panel);
node.SetValue("CompoundsKds", compoundsKds);
node.SetValue("MutationRelevance", mutationRelevance);
node.SetValue("MutationReferences", mutationReferences);
node.SetValue("DocumentPublishTo", null);
node.Update();
updatedKinaseCount++;
vm.CheckIn(node, null, null);
WorkflowInfo wi = wm.GetNodeWorkflow(node);
if (node.IsPublished)
{
wm.AutomaticallyPublish(node, wi, null);
}
}
else
{
node = TreeNode.New(className, tp);
node.DocumentName = ambitGeneSymbol;
node.NodeName = ambitGeneSymbol;
node.SetValue("Title", title);
node.SetValue("TechnologyPlatform", technologyPlatform);
node.SetValue("AmbitGeneSymbol", ambitGeneSymbol);
node.SetValue("TargetDescription", targetDescription);
node.SetValue("EntrezGeneSymbol", entrezGeneSymbol);
node.SetValue("EntrezGeneID", entrezGeneID);
node.SetValue("Aliases", aliases);
node.SetValue("KinaseGroup", kinaseGroup);
node.SetValue("Species", species);
node.SetValue("AccessionNumber", accessionNumber);
node.SetValue("KinaseConstruct", kinaseConstruct);
node.SetValue("KinaseForm", kinaseForm);
node.SetValue("ExpressionSystem", expressionSystem);
if (!(dr["AverageZValue"] is DBNull))
{
node.SetValue("AverageZValue", avgZValue);
}
node.SetValue("Panel", panel);
node.SetValue("CompoundsKds", compoundsKds);
node.SetValue("MutationRelevance", mutationRelevance);
node.SetValue("MutationReferences", mutationReferences);
node.SetValue("DocumentPublishTo", null);
node.SetValue("DocumentCulture", "en-US");
TreeNode parentNode = tp.SelectSingleNode("DiscoveRx", kinaseAliasPath, "en-US");
node.Insert(parentNode);
//vm.CheckIn(node, null, null);
newKinaseCount++;
}
}
}
ArchiveItems(archivedKinaseCount, "dx.kinasedatasheet.selectarchivekinases");
}
In addition to refactoring your routine I'd recommend creating some extension methods to save you some typing. For example, here's the an extension for parsing your doubles:
public static class Extensions
{
public static double ToDoubleIfNotDBNull(this object item)
{
if (item is DBNULL) return 0;
return double.Parse(item.ToString());
}
}
So then your code becomes:
double avgZValue = dr["AverageZValue"].ToDoubleIfNotDBNull();
You can just refactor your code so you don't need to set the node values in different cases:
private void SyncKinases()
{
DataSet ds = new DataSet();
ds = gn.ExecuteQuery("dx.kinasedatasheet.selectstagingkinases", null);
TreeProvider tp = new TreeProvider(ui);
VersionManager vm = new VersionManager(tp);
TreeNode node;
WorkflowManager wm = new WorkflowManager(tp);
if (ds.Tables[0].Rows.Count > 0)
{
foreach (DataRow dr in ds.Tables[0].Rows)
{
string className = "dx.kinasedatasheet";
string title = dr["Title"].ToString();
string technologyPlatform = dr["TechnologyPlatform"].ToString();
string ambitGeneSymbol = dr["AmbitGeneSymbol"].ToString();
string targetDescription = dr["TargetDescription"].ToString();
string entrezGeneSymbol = dr["EntrezGeneSymbol"].ToString();
int entrezGeneID = int.Parse(dr["EntrezGeneID"].ToString());
string aliases = dr["Aliases"].ToString();
string kinaseGroup = dr["KinaseGroup"].ToString();
string species = dr["Species"].ToString();
string accessionNumber = dr["AccessionNumber"].ToString();
string kinaseConstruct = dr["KinaseConstruct"].ToString();
string kinaseForm = dr["KinaseForm"].ToString();
string expressionSystem = dr["ExpressionSystem"].ToString();
double avgZValue = 0;
if (!(dr["AverageZValue"] is DBNull))
{
avgZValue = double.Parse(dr["AverageZValue"].ToString());
}
string panel = dr["Panel"].ToString();
string compoundsKds = dr["CompoundsKds"].ToString();
string mutationRelevance = dr["MutationRelevance"].ToString();
string mutationReferences = dr["MutationReferences"].ToString();
string kinaseAliasPath = "/Kinase-Data-Sheets";
bool isNewNode = false;
if (!(dr["NodeID"] is System.DBNull))
{
node = tp.SelectSingleNode(int.Parse(dr["NodeID"].ToString()));
vm.CheckOut(node);
}
else
{
node = TreeNode.New(className, tp);
node.SetValue("DocumentCulture", "en-US");
isNewNewNode = true;
}
node.DocumentName = ambitGeneSymbol;
node.NodeName = ambitGeneSymbol;
node.SetValue("Title", title);
node.SetValue("TechnologyPlatform", technologyPlatform);
node.SetValue("AmbitGeneSymbol", ambitGeneSymbol);
node.SetValue("TargetDescription", targetDescription);
node.SetValue("EntrezGeneSymbol", entrezGeneSymbol);
node.SetValue("EntrezGeneID", entrezGeneID);
node.SetValue("Aliases", aliases);
node.SetValue("KinaseGroup", kinaseGroup);
node.SetValue("Species", species);
node.SetValue("AccessionNumber", accessionNumber);
node.SetValue("KinaseConstruct", kinaseConstruct);
node.SetValue("KinaseForm", kinaseForm);
node.SetValue("ExpressionSystem", expressionSystem);
if (!(dr["AverageZValue"] is DBNull))
{
node.SetValue("AverageZValue", avgZValue);
}
node.SetValue("Panel", panel);
node.SetValue("CompoundsKds", compoundsKds);
node.SetValue("MutationRelevance", mutationRelevance);
node.SetValue("MutationReferences", mutationReferences);
node.SetValue("DocumentPublishTo", null);
if (isNewNode)
{
TreeNode parentNode = tp.SelectSingleNode("DiscoveRx", kinaseAliasPath, "en-US");
node.Insert(parentNode);
//vm.CheckIn(node, null, null);
newKinaseCount++;
}
else
{
node.Update();
updatedKinaseCount++;
vm.CheckIn(node, null, null);
WorkflowInfo wi = wm.GetNodeWorkflow(node);
if (node.IsPublished)
{
wm.AutomaticallyPublish(node, wi, null);
}
}
}
}
ArchiveItems(archivedKinaseCount, "dx.kinasedatasheet.selectarchivekinases");
}
You now also don't need all of those temporary variables from dr columns since they will only be used once. Removing those will make your method much shorter and more readable.
Just create a new method and send the values as parameters.
void SetNodeValues(Node node, DataRow row)
{
string title = dr["Title"].ToString();
....
node.SetValue("Title", title);
...
}
You might be able to do it all with a for loop (untested and not match your variables)
foreach(var col in Table.Columns)
node.SetValue(col.Name, dr[col]);
If you were using an ORM, you could send an object instead of the DataRow but that is beyond the scope of this question.

CSV string to DataTable

I have following string,
I want to convert it to DataTable
"Id,Name ,Dept\r\n1,Mike,IT\r\n2,Joe,HR\r\n3,Peter,IT\r\n"
I can create it using String.Split and iterating through collection.
But I need efficient way (using C# 4.0 features)
How to create table using LINQ or lambda.
I don't know if that what are you looking for :
string s = "Id,Name ,Dept\r\n1,Mike,IT\r\n2,Joe,HR\r\n3,Peter,IT\r\n";
DataTable dt = new DataTable();
string[] tableData = s.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var col = from cl in tableData[0].Split(",".ToCharArray())
select new DataColumn(cl);
dt.Columns.AddRange(col.ToArray());
(from st in tableData.Skip(1)
select dt.Rows.Add(st.Split(",".ToCharArray()))).ToList();
I Think this method will be useful. This method can be used for both CSVString or CsvFilePath. If you want to convert CsvFilePath then you have to specify first path has true else false.
public DataTable ConvertCsvStringToDataTable(bool isFilePath,string CSVContent)
{
//CSVFilePathName = #"C:\test.csv";
string[] Lines;
if (isFilePath)
{
Lines = File.ReadAllLines(CSVContent);
}
else
{
Lines = CSVContent.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
}
string[] Fields;
Fields = Lines[0].Split(new char[] { ',' });
int Cols = Fields.GetLength(0);
DataTable dt = new DataTable();
//1st row must be column names; force lower case to ensure matching later on.
for (int i = 0; i < Cols; i++)
dt.Columns.Add(Fields[i].ToLower(), typeof(string));
DataRow Row;
for (int i = 1; i < Lines.GetLength(0); i++)
{
Fields = Lines[i].Split(new char[] { ',' });
Row = dt.NewRow();
for (int f = 0; f < Cols; f++)
Row[f] = Fields[f];
dt.Rows.Add(Row);
}
return dt;
}
using System;
using System.Xml;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public static string DataTableToString(DataTable dtData)
{
string sData = null;
StringBuilder sBuffer = null;
string Token = null;
int i = 0;
int j = 0;
sBuffer = new StringBuilder();
sBuffer.Append(#"<TABLE>");
sBuffer.Append(#"<TR>");
foreach (DataColumn Col in dtData.Columns)
{
sBuffer.Append(#"<TH ColType='")
.Append(Convert.ToString(Col.DataType))
.Append(#"'>")
.Append(Col.ColumnName.Replace("&", ""))
.Append(#"</TH>");
}
sBuffer.Append(#"</TR>");
i = 0;
foreach (DataRow rw in dtData.Rows)
{
sBuffer.Append(#"<TR>");
j = 0;
foreach (DataColumn Col in dtData.Columns)
{
if (!Convert.IsDBNull(rw[Col.ColumnName]))
{
Token = Convert.ToString(rw[Col.ColumnName]);
}
else
{
Token = null;
}
sBuffer.Append(#"<TD>").Append(Token).Append(#"</TD>");
j++;
}
sBuffer.Append(#"</TR>");
i++;
}
sBuffer.Append(#"</TABLE>");
sData = sBuffer.ToString();
return sData;
}
public static DataTable StringToDataTable(string sXmlData)
{
DataTable dtData = null;
XmlDocument xmlDoc = null;
XmlNode RootNode = null;
XmlNodeList TRList = null;
XmlNodeList THList = null;
XmlNodeList TDList = null;
int i = 0;
int j = 0;
XmlAttribute DataTypeAttrib = null;
string sDataType = null;
DataColumn Col = null;
Type ColType;
string Token = null;
DataRow newRw = null;
xmlDoc = new XmlDocument();
xmlDoc.LoadXml(sXmlData);
RootNode = xmlDoc.SelectSingleNode("/TABLE");
if (RootNode != null)
{
dtData = new DataTable();
i = 0;
TRList = RootNode.SelectNodes("TR");
foreach (XmlNode TRNode in TRList)
{
if (i == 0)
{
THList = TRNode.SelectNodes("TH");
foreach (XmlNode THNode in THList)
{
DataTypeAttrib = THNode.Attributes["ColType"];
sDataType = DataTypeAttrib.Value;
ColType = Type.GetType(sDataType);
Col = new DataColumn(THNode.InnerText, ColType);
if (!dtData.Columns.Contains(Col.ColumnName))
{
dtData.Columns.Add(Col);
}
}
}
else
{
newRw = dtData.NewRow();
j = 0;
TDList = TRNode.SelectNodes("TD");
foreach (XmlNode TDNode in TDList)
{
ColType = dtData.Columns[j].DataType;
Token = TDNode.InnerText;
if (!string.IsNullOrEmpty(Token))
{
try
{
newRw[j] = Convert.ChangeType(Token, ColType);
}
catch
{
if (ColType == typeof(DateTime))
{
newRw[j] = DateTime.ParseExact(Token, "yyyyMMdd", System.Globalization.CultureInfo.InvariantCulture);
}
}
}
else
{
newRw[j] = Convert.DBNull;
}
j++;
}
dtData.Rows.Add(newRw);
}
i++;
}
}
return dtData;
}

Categories