LINQ, parser un fichier texte

Bonjour,

Suite à une conversation avec un éminent spécialiste de mammifères au long cou, je me suis dis que ça pouvait vous intéresser :
Afin de jouer avec LINQ j’ai décidé de l’utiliser pour parser un fichier texte. La première chose intéressante que j’ai vu, c’est de construire ces “requêtes” sans forcément provoquer “l’exécution” (façon de parler).

Une fois que j’ai stocké le contenu de mon fichier texte dans une chaine, je fais une requête de base qui va me renvoyer un IEnumerable qui va contenir chaque ligne de mon fichier, le tout trimer.

[code]var contenuFichierTexte = GetFromTextFile(“mon_fichier.txt”);

var qBase = from c in contenuFichierTexte
select c.Trim().ToLower();[/code]
Jusqu’ici tout va bien, je récupère bien ce que je veux. Comme beaucoup de fichier, celui-ci est composé d’un en-tête et d’une partie données séparée par un mot-clé ‘Data’ :

string dataKeyword = “data”;
var qHeader = qBase.TakeWhile(a => a!= dataKeyword);
var qData = qBase.SkipWhile(a => a!= dataKeyword).Skip(1);

Je peux maintenant ‘parser’ mes 2 parties. Dans le header, le fichier est organisé comme ceci :

property "value" property2 "value"
donc je boucle bêtement sur mon itération qHeader :

[code]foreach (var w in qHeader)
{
// Requête qui permet de récupéré une énumération des ‘mots’ contenus dans la ligne (ligne splitée)
var qLineBase = from c in w.Split(’ ')
select c;

// bête switch en fonction de la propriété
switch (qLineBase.ElementAt(0).ToString())
{
	case "version":
		monObjet.Version = Convert.ToInt32(qLineBase.ElementAt(1).Trim('"'));
		break;

	...
}

}[/code]

Rien de compliqué même si je pense que ça peut être optimisé à mon avis (reste à savoir comment).

Pour la partie data, j’ai des données comme ceci :

et la j’aimerai récupérer la structure de mon fichier en gros comme ceci :

objetsgraphiques | |_____ region | |_____polygone | | |____point | | |____point | |_____polygone | |____point | |____point | |____point | |____point | |_____ polyline | |_____point | |_____point | |_____ polyline |_____point |_____point

J’aurai voulu pouvoir récupérer toutes les ‘regions’ par exemple ainsi que leurs polygones
Pour récupérer les polyline (noté PLINE dans le fichier) j’ai fait la requête suivante :

var qPline = from c in qData
where c.StartsWith(“pline”)
select qData.Take(Convert.ToInt32(c.Substring(c.LastIndexOf(’ '))) +
1).Skip(1);

le problème c’est que je récupère bien 2 IEnumerable mais les valeurs sont identiques (voir image ci-dessous)

Donc là je galère…

je me dis que c’est peut-être une mauvaise idée d’avoir voulu splité mon fichier texte en un enumérable de string car on casse tout l’ensemble du fichier non ?
Donc si vous avez des idées / ressources, je prends…

Merci !

Question subsidiaire : existe-t-il un utilitaire qui convertit à la volée la syntax sugar vers la syntaxe pointée et vice-versa ?

Hmm, vu comme ca, tu perds un des gros avantages dont tu voulais tirer parti : le streming.
En effet, tu commence par charger tout ton fichier avant de créer tes objets, c’est dommage!

Autre point, Linq est plus adapté au requètage sur des graphes structurés. Pour moi, il vaut mieux que tu implémentes un parseur basé sur des itérateurs, qui te permettra cette fois d’avoir un vrai strema bout en bout: Je lis la definition d’un PLine, hop, je le retourne et je commence à lire le second.

Je t’enverrai tout à l’heure un bout de code que je viens de faire qui stream la partie data de tes fichiers.

Allez hop, c’est brut de décoffrage, pas commenté, sans gestion d’exception, mais dans le principe, ca te stream tes regions et polylines (ce qui te permet par exemple de les dessiner au fur et à mesure que tu les lis).

C’est beau de voir des trucs comme:

public Point[] Points { get; set; }

:slight_smile: Et aussi, et c’est pas pour girafologue, mais c’est pas parceque var c’est pratique qu’il faut en abuser, ca rend parfois le code super dur a lire…

j’avoue, mea culpa :crying:

[edit]Juste, pour ma défense, j’ai écrit ce code en 20 minutes montre en main, et je promets que ce soir je réciterai 50 fois “je n’utiliserai pas var à la place de int” :)[/edit]

[quote=« girafologue, post:5, topic: 46671 »]j’avoue, mea culpa :cry:

[edit]Juste, pour ma défense, j’ai écrit ce code en 20 minutes montre en main, et je promets que ce soir je réciterai 50 fois « je n’utiliserai pas var à la place de int » :crying:[/edit][/quote]

Et pas de boucle hein ! :slight_smile: Sinon je regarde ça ce midi. En tout cas, merci pour l’exemple, je crois qu’il va m’aider à comprendre pas mal de chose !!

Ok !! J’avais fait un raccourci foireux dans ma tête, en croyant que Linq permettait de ne pas implémenter les différents IEnumerable pour récupérer ce qu’on voulait.

Donc à la limite c’est ultérieurement (une fois que mon objet est construit) que je pourrais requêter dessus (puique mon objet est structuré lui).

Merci beaucoup !