Click here to Skip to main content
15,885,366 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a CSV file, whose headers are defined in separate XML as shown below.
XML
<columns>
      <column value="FirstName" required="true"/>
      <column value="LastName" required="false"/>
      <column value="Age" required="true"/>
    </columns>

I need to parse the CSV, check rules and save it. Effectively, I need to find that first column is FirstName, second column is LastName based on positions in XML rather than fixed position. I also have other rules which is like FirstName must be alphabets only, age can be number only which are based on column name and not position.

So, I need to get the data as per column name in XML and then apply rules.

Any pointer/idea will be helpful.
Thanks,
Posted
Comments
[no name] 21-May-15 20:35pm    
Just parse the XML to create your table then fill it from the csv. What's the question? Why 2 files - why not a self describing csv or better still all XML.
MT_ 22-May-15 3:01am    
question was on how to have dynamic header names. Both you and solution posted below rightly pointed me to right direction of DataTable. Now only confusing is checking value of each row against required attribute of the XML. Thanks for reading the question and pointing to right direction.

1 solution

Hi,

This solution will the parse the XML, CSV file and have the data in a datatable. You can change it to any form that suits your requirement. Here are the steps:
Parsing XML
Parse the XML and keep the column names in a
C#
List<string></string>
for selecting the required columns once CSV file is parsed. In order for this to work, you have to install HtmlAgilityPack. Run the following command in package manager console to install it:
Install-Package HtmlAgilityPack

and add Using HtmlAgilityPack to you class.
Here is the code for parsing the XML (I used the XML you provided for sample):
C#
string columnXML = "<columns><column value=\"FirstName\" required=\"true\"/><column value=\"LastName\" required=\"false\"/><column value=\"Age\" required=\"true\"/></columns>";
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(columnXML);
            List<string> columnNames = new List<string>();
            HtmlNodeCollection nodes = doc.DocumentNode.SelectNodes("//columns");
            HtmlNodeCollection childNodes = nodes[0].ChildNodes;
            foreach (HtmlNode childNode in childNodes)
            {
                columnNames.Add(childNode.GetAttributeValue("value","NotFound"));
            }

Now the column names are present in columnNames list.

Parse CSV file
Here is one of the simplest methods to parse CSV and load into datatable. Assuming CSV contains the column names as the first row.
C#
var lines = File.ReadAllLines(//filepath);
DataTable testDataTable = new DataTable();
var headers = lines.First().Split(',');
foreach (var header in headers)
{
    testDataTable.Columns.Add(header);
}
foreach (var line in lines.Skip(1))
{
    testDataTable.Rows.Add(line.Split(','));
}

Select required columns
DataTable finalDataTable = testDataTable.DefaultView.ToTable(false, columnNames.ToArray());


This may not be the optimal solution to your needs. But it gives an idea of how you can do what you want. Hope this helps.
 
Share this answer
 
Comments
MT_ 22-May-15 2:46am    
Thanks. You put me in the right track with DataTable. I got the column names from XML using XDocument and added in DataTable and parsed CSV to add rows to it. This gave me the datatable I needed.
Only thing now remains is based on "required" attribute, check whether particular column is not null in the row (which is parsed from CSV). Let me know if you have any suggestion for that.
Thanks once again.
Mathi Mani 22-May-15 13:53pm    
Hi, get the required attribute while getting the value attribute and create a Dictionary<string,string> with these values, having column name as key. Then you can do the validation for all the columns that have the required attribute as true.
MT_ 23-May-15 4:34am    
Thanks Mathi Mani, Much appreciate. Eventually, I took exact same path yesterday to achieve the goal and it worked out nicely. Thanks very much for ideas.

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900