CSV bestand omzetten naar generieke lijst
Probleem
Gegevens kunnen manipuleren is iets wat elke programmeur moet kunnen. Het csv formaat is een algemeen bekend en gebruik formaat om gegevens van het ene naar het andere systeem over te brengen.
Als voorbeeld nemen we de postcodes van België. Je kan die gemakkelijk downloaden van de BPost website. We downloaden die Excel formaat. Zowel de Franse als de Nederlandse versie. We voegen beiden samen en exporteren het geheel als csv met het pipe '|' teken als scheidingsteken. We slaan dat op in een bestand met de naam Postcodes.csv
en plaatsen dit in de map Data
.
Hieronder zie je een uitreksel uit het Postcodes.csv bestand dat we op basis van de BPost Excel bestanden hebben gemaakt. Als scheidingsteken heb ik het | teken ingesteld:
1495|VILLERS-LA-VILLE|Waals-Brabant|VILLERS-LA-VILLE|Brabant Wallon 1500|HALLE|Vlaams-Brabant|HALLE|Brabant Flamand 1501|Buizingen|Vlaams-Brabant|Buizingen|Brabant Flamand 1502|Lembeek|Vlaams-Brabant|Lembeek|Brabant Flamand 1540|Herfelingen|Vlaams-Brabant|Herfelingen|Brabant Flamand 1540|HERNE|Vlaams-Brabant|HERNE|Brabant Flamand 1541|Sint-Pieters-Kapelle|Vlaams-Brabant|Sint-Pieters-Kapelle|Brabant Flamand 1547|BEVER|Vlaams-Brabant|BIÉVÈNE|Brabant Flamand 1560|HOEILAART|Vlaams-Brabant|HOEILAART|Brabant Flamand 1570|GALMAARDEN|Vlaams-Brabant|GALMAARDEN|Brabant Flamand 1570|Tollembeek|Vlaams-Brabant|Tollembeek|Brabant Flamand 1570|Vollezele|Vlaams-Brabant|Vollezele|Brabant Flamand 1600|Oudenaken|Vlaams-Brabant|Oudenaken|Brabant Flamand 1600|Sint-Laureins-Berchem|Vlaams-Brabant|Sint-Laureins-Berchem|Brabant Flamand 1600|SINT-PIETERS-LEEUW|Vlaams-Brabant|SINT-PIETERS-LEEUW|Brabant Flamand
Elke regel in het CSV bestand stemt overeen met één rij uit een tabel (relationele databanken terminologie) of één entiteit (ERD terminoglogie). Het pipe '|' teken geeft de kolommen (terminologie relationele databanken) of de attributen (ERD terminologie) aan.
Design
We moeten dus eerst regel per regel de tekst doorlopen en daarna elke regel opslitsen in 5 kolommen. Als splitsingsteken gebruiken we het pipe '|' teken. Elke kolom waarde moeten we tenslotte toekennen aan de eigenschappen van de Postcode
klasse. Vooraleer aan de volgende regel te beginnen stoppen we het pas gemaakte Postcode
object in de generieke lijst.
We gaan gelaagd werken.
BLL
De code die de gegevens als een object voorstelt stoppen we in de Business Logc Layer (BBL)
Velden
naam | bereik | type | omschrijving |
code | private | string | de postcode |
plaats | private | string | naam van de plaats in het Nederlands |
provincie | private | string | naam van de provincie in het Nederlands |
localite | private | string | naam van de plaats in het Frans |
province | private | string | naam van de provincie in het Frans |
Eigenschappen
naam | bereik | type | omschrijving |
Code | public | string | getter en setter voor code |
Plaats | public | string | getter en setter plaats |
Provincie | public | string | getter en setter voor provincie |
Localite | public | string | getter en setter voor localite |
Province | public | string | getter en setter voor province |
Oplossing
We beginnen met een map te maken in het learning project met de naam Postcode.
We makken een klasse met de naam PostCode
in de namespace DotNetCore.Learning.Dal
in het bestand met de naam Bll.cs.
namespace DotNetCore.Learning.Bll { public class Postcode { private string code; public string Code { get { return code; } set { code = value; } } private string plaats; public string Plaats { get { return plaats; } set { plaats = value; } } private string provincie; public string Provincie { get { return provincie; } set { provincie = value; } } private string localite; public string Localite { get { return localite; } set { localite = value; } } private string province; public string Province { get { return province; } set { province = value; } } } }
DAL
De code die de gegevens inleest stoppen we in de data access layer (DAL).
Methoden
naam | bereik | type | omschrijving |
LeesUitCsvBestand | public | string | retourneert de inhoud van het CSV bestand. |
GetList | public | List |
retourneert een generieke lijst met Postcode objecten |
ToObject | public | Postcode | split een lijn in kolommen en stopt de waarden in een Postcode object en retourneert tenslotte het nieuw gemaakt object |
We maken een klasse met de naam PostCode
in de namespace DotNetCore.Learning.Bll
in het bestand met de naam Bll.cs.
using System.Collections.Generic; namespace DotNetCore.Learning.Dal { class Postcode { public static string LeesUitCsvBestand() { Dal.Tekstbestand bestand = new Dal.Tekstbestand(); // je zou voor de bestandsnaam eventueel ook een property kunnen gebruiken // zodat die hier niet hard coded staat bestand.FileName = @"Data\Postcodes.csv"; bestand.Lees(); return bestand.Text; } public static List<Bll.Postcode> GetList() { string[] postcodes = LeesUitCsvBestand().Split('\n'); List<Bll.Postcode> list = new List<Bll.Postcode>(); foreach (string s in postcodes) { if (s.Length > 0) { list.Add(ToObject(s)); } } return list; } public static Bll.Postcode ToObject(string line) { Bll.Postcode postcode = new Bll.Postcode(); string[] values = line.Split('|'); postcode.Code = values[0]; postcode.Plaats = values[1]; postcode.Provincie = values[2]; postcode.Localite = values[3]; postcode.Province = values[4]; return postcode; } } }
Presentation Layer
We maken een eenvoudige presentation layer voor de Console. Maak de klasse met de naam Postcode
in de namespace DotNetCore.Learning.PresentationLayer
in het bestand met de naam PresentationLayer.cs.
Voeg in de klasse de volgende methode toe:
using System;
namespace DotNetCore.Learning.PresentationLayer
{
class Postcode
{
public static void ShowList()
{
foreach (Bll.Postcode postcode in Dal.Postcode.GetList())
{
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}",
postcode.Code,
postcode.Plaats,
postcode.Provincie,
postcode.Localite,
postcode.Province);
}
}
}
}
En probeer het voorbeeld uit in de Main
methode van de Program
klasse in Program.cs:
using System;
namespace DotNetCore.Learning
{
class Program
{
static void Main(string[] args)
{
//Console.WriteLine(TryOut.ReadFromCSVFile());
//TryOut.ArrayListSample();
//TryOut.DictionarySample();
//Console.WriteLine(TryOut.GenericListSimpleExample());
PresentationLayer.Postcode.ShowList();
Console.ReadKey();
}
}
}