IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

Parser un fichier Json


Sujet :

Contribuez

  1. #1
    Membre chevronné Avatar de laurent30s
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 881
    Points : 1 768
    Points
    1 768
    Par défaut Parser un fichier Json
    Ça fait plusieurs fois que je vois que certains ont des difficultés pour parser du Json.

    Dernièrement par rapport à une demande pour parser un flux d'allocine, j'ai fait une réponse qui bien que fonctionnelle ne me convenait pas.
    http://www.developpez.net/forums/d13...page-internet/

    Du coup j'ai profité d'un week-end pluvieux pour pousser la réflexion un peu plus loin.

    La contribution consiste en un procédure JsonLit() un peut similaire à la fonction existante XMLLit().
    Cette procédure a 3 paramètres :
    - sSourceJson = chaîne contenant le code Json à analyser.
    - sChemin_elem_a_lire = chaîne contenant une requête à exécuter qui ressemble à XPath.
    - sReponse_si_non_trouve = texte à renvoyer si l'élément n'a pas été trouvé. Ce paramètre est optionnel, par défaut, il correspond à une chaîne vide ("").

    Exemple de requête XPath :
    /COMMANDE/NUMEROCDE -----------------> Sélectionne la rubrique NUMEROCDE de la COMMANDE
    /COMMANDE/LIGNECDE[2]/NUMEROLIGNE ---> Sélectionne la rubrique NUMEROLIGNE de la 2ème LIGNECDE de la COMMANDE

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    PROCEDURE JsonLit(sSourceJson est une chaîne,sChemin_elem_a_lire est une chaîne,sReponse_si_non_trouve est une chaîne = "")
     
    // sSourceJson sans les {/} début/fin 
    sSourceJson_extrait est une chaîne = Milieu(sSourceJson,2, Taille(sSourceJson) - 2)
     
    nSourceJson_extrait_taille est un entier
    sSourceJson_sous_chaine est une chaîne
    sSous_chaine est une chaîne
    bTrouve est un booléen = Vrai
    sElement est une chaîne
    sElement_extrait est une chaîne
    nElement_nb est un entier
    nElement_no_ligne est un entier
    nPosition_debut est un entier
    nPosition_fin est un entier
    nPosition_debut_parenthese_crochet est un entier
    sPile est une chaîne
    i,j est un entier
     
    nElement_nb = ChaîneOccurrence(sChemin_elem_a_lire,"/")
    sElement    = ExtraitChaîne(sChemin_elem_a_lire,rangPremier,"/")
    sElement    = ExtraitChaîne(sChemin_elem_a_lire,rangSuivant,"/")
    TANTQUE sElement <> EOT
    	i += 1
    	nPosition_debut = Position(sElement,"[")
    	nPosition_fin   = Position(sElement,"]")
    	SI nPosition_debut = 0 ET nPosition_fin = 0 ALORS
    		sElement_extrait  = sElement
    		nElement_no_ligne = 0
    	SINON SI nPosition_debut > 0 ET nPosition_fin > 0 ALORS
    		sElement_extrait  = Gauche(sElement,nPosition_debut - 1)
    		nElement_no_ligne = Val(Milieu(sElement,nPosition_debut + 1,nPosition_fin - 1))
    	SINON
    		// Élément avec crochet manquant RETOUR
    		RENVOYER sReponse_si_non_trouve
    	FIN
     
    	nPosition_debut = Position(sSourceJson_extrait,"""" + sElement_extrait + """:")
    	SI nPosition_debut = 0 ALORS
    		// Élément non trouvé RETOUR
    		RENVOYER sReponse_si_non_trouve	
    	SINON
    		nSourceJson_extrait_taille = Taille(sSourceJson_extrait)
    		sSourceJson_sous_chaine   = Milieu(sSourceJson_extrait,nPosition_debut + Taille(sElement_extrait) + 3, 1)
    		SELON sSourceJson_sous_chaine
    			CAS "{"
    		 		// Objet
    		 		nPosition_debut_parenthese_crochet = Position(sSourceJson_extrait,"{",nPosition_debut)
    		 		sPile = ""
    		 		POUR j = nPosition_debut_parenthese_crochet A nSourceJson_extrait_taille
    		 			sSous_chaine = Milieu(sSourceJson_extrait, j, 1)
    		 			SELON sSous_chaine
    		 				CAS "{", "["
    		 					sPile += sSous_chaine
    		 				CAS "}", "]"
    		 					SI Droite(sSous_chaine,1) = sSous_chaine ALORS
    		 						sPile = Gauche(sPile,Taille(sPile) - 1)
    		 					SINON
    		 						// Mauvaise chronologie des {[]} RETOUR
    								RENVOYER sReponse_si_non_trouve
    		 					FIN
    		 			FIN
    		 			SI sPile = "" ALORS
    		 				nPosition_fin = j
    		 				SORTIR
    		 			FIN	
    		 		FIN
    		 		SI sPile <> "" ALORS
    					// Mauvaise chronologie des {[]} RETOUR
    		 			RENVOYER sReponse_si_non_trouve
    		 		FIN
    		 		// récupère l'objet sans les {/} début/fin et passe à l'élément suivant
    		 		sSourceJson_extrait = Milieu(sSourceJson_extrait,nPosition_debut_parenthese_crochet + 1, nPosition_fin - nPosition_debut_parenthese_crochet - 1)		 		
     
    			CAS "["
    		 		// Tableau
    		 		SI nElement_no_ligne = 0 ALORS
    					RENVOYER sReponse_si_non_trouve
    		 		FIN
    				nPosition_debut_parenthese_crochet = Position(sSourceJson_extrait,"[",nPosition_debut)
    				sPile = ""
    				POUR j = nPosition_debut_parenthese_crochet A nSourceJson_extrait_taille
    					sSous_chaine = Milieu(sSourceJson_extrait, j, 1)
    					SELON sSous_chaine
    						CAS "{", "["
    							sPile += sSous_chaine
    						CAS "}", "]"
    							SI Droite(sSous_chaine,1) = sSous_chaine ALORS
    								sPile = Gauche(sPile,Taille(sPile) - 1)
    							SINON
    								// Mauvaise chronologie des {[]} RETOUR
    								RENVOYER sReponse_si_non_trouve
    							FIN
    					FIN
    					SI sPile = "" ALORS
    						nPosition_fin = j
    						SORTIR
    					FIN	
    				FIN
    				SI sPile <> "" ALORS
    					// Mauvaise chronologie des {[]} RETOUR
    					RENVOYER sReponse_si_non_trouve
    				FIN
    				// récupère toutes les lignes du tableau sans les [{/}] début/fin 
    				sSourceJson_extrait = Milieu(sSourceJson_extrait,nPosition_debut_parenthese_crochet + 2, nPosition_fin - nPosition_debut_parenthese_crochet - 3)
    		 		// récupère le numéro de ligne demandé dans le tableau et passe à l'élément suivant
    		 		sSourceJson_extrait = ExtraitChaîne(sSourceJson_extrait,nElement_no_ligne,"},{")	 		
     
    			CAS """"
    		 		// Valeur chaine
    		 		SI i <> nElement_nb ALORS
    		 			// Valeur pas sur dernier élément du chemin RETOUR
    		 			RENVOYER sReponse_si_non_trouve
    		 		FIN
    		 		nPosition_debut = nPosition_debut + Taille(sElement_extrait) + 4
    		 		nPosition_fin   = 0
    				SI Position(sSourceJson_extrait,""",",nPosition_debut) > 0 ALORS
    					nPosition_fin = Position(sSourceJson_extrait,""",",nPosition_debut)
    				FIN		
    				SI Position(sSourceJson_extrait,"""},",nPosition_debut) > 0 ET Position(sSourceJson_extrait,"""},",nPosition_debut) < nPosition_fin ALORS
    					nPosition_fin = Position(sSourceJson_extrait,"""},",nPosition_debut)
    				FIN
    				SI Position(sSourceJson_extrait,"""}],",nPosition_debut) > 0 ET Position(sSourceJson_extrait,"""}],",nPosition_debut) < nPosition_fin ALORS
    					nPosition_fin = Position(sSourceJson_extrait,"""}],",nPosition_debut)
    				FIN
    				SI nPosition_fin = 0 ALORS
    					nPosition_fin = Taille(sSourceJson_extrait)
    				FIN
    				// valeur trouvée	
    		 		RENVOYER Milieu(sSourceJson_extrait,nPosition_debut,nPosition_fin - nPosition_debut)		 		
     
    			AUTRE CAS
    		 		// valeur numérique
    				SI i <> nElement_nb ALORS
    					// Valeur pas sur dernier élément du chemin RETOUR
    					RENVOYER sReponse_si_non_trouve
    				FIN
    				nPosition_debut = nPosition_debut + Taille(sElement_extrait) + 3
    				nPosition_fin   = 0
    				SI Position(sSourceJson_extrait,",",nPosition_debut) > 0 ALORS
    					nPosition_fin = Position(sSourceJson_extrait,",",nPosition_debut)
    				FIN		
    				SI Position(sSourceJson_extrait,"},",nPosition_debut) > 0 ET Position(sSourceJson_extrait,"},",nPosition_debut) < nPosition_fin ALORS
    					nPosition_fin = Position(sSourceJson_extrait,"},",nPosition_debut)
    				FIN
    				SI Position(sSourceJson_extrait,"}],",nPosition_debut) > 0 ET Position(sSourceJson_extrait,"}],",nPosition_debut) < nPosition_fin ALORS
    					nPosition_fin = Position(sSourceJson_extrait,"}],",nPosition_debut)
    				FIN
    				SI nPosition_fin = 0 ALORS
    					nPosition_fin = Taille(sSourceJson_extrait) + 1
    				FIN
    				// valeur trouvée	
    				RENVOYER Milieu(sSourceJson_extrait,nPosition_debut,nPosition_fin - nPosition_debut)
    		 FIN			 
    	FIN
    	sElement = ExtraitChaîne(sChemin_elem_a_lire,rangSuivant,"/")
    FIN
     
    RENVOYER sReponse_si_non_trouve
    exemple d'appel de la procédure pour parser un flux d'allocine (en l’occurrence tous les filmes correspondant au mot avatar) pour remplir un table

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    sChaine_reponse est une chaîne
    nNb_film,i est un entier
    sURL sont des chaîne = ChaîneConstruit("http://api.allocine.fr/rest/v3/search?partner=YW5kcm9pZC12M3M&filter=movie&q=%1&format=json","avatar")
     
    TableSupprimeTout(TABLE_Film)
     
    // Lance la requête
    SI PAS HTTPRequête(sURL) ALORS
    	Erreur(ErreurInfo())
    	RETOUR
    FIN
    // Récupère le résultat de la requête
    sChaine_reponse = HTTPDonneRésultat(httpRésultat)
     
    nNb_film = JsonLit(sChaine_reponse,"/feed/count")
     
    POUR i = 1 A nNb_film
    	TableAjouteLigne(TABLE_Film,JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/code"), ...
    								JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/originalTitle"), ...
    								JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/title"), ...
    								JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/productionYear"), ...
    								Remplace(JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/release/releaseDate"),"-",""), ...
    								JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/castingShort/directors"), ...
    								JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/castingShort/actors"), ...
    								JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/statistics/pressRating"), ...
    								JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/statistics/userRating"), ...
    								Remplace(JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/poster/href"),"/",""), ...
    								Remplace(JsonLit(sChaine_reponse,"/feed/movie[" + i + "]/link[1]/href"),"/",""))
    FIN
    Attention ce code n'est pas forcément exhaustif pour parser du Json.
    Je n'ai pas repris un algorithme existant. J'ai juste observé le flux d'allocine que j'ai interprété.
    Sur ce flux ce code fonctionne bien. Il repère les objets, les tableaux, et les rubriques contenant des valeurs.

    Lors de toute 1ère utilisation je vous conseille de vous assurer que le format est bien reconnu et que les données retournées sont bien conformes à celles contenues dans le fichier Json.

    Si certains veulent améliorer/compléter cette contribution j'en serais ravi...
    Le traitement a un peu de lenteur qui peut être important sur des très gros fichiers. Il y a sans doute possibilité d’accélérer cette vitesse de traitement.

    Bonne utilisation.
    Bon dev
    Laurent

    - C’est génial.
    - Non c’est bizarre.
    - Justement quand c’est simple y’a des milliers de réponses et quand c’est bizarre y’en a aucune.

  2. #2
    Membre éprouvé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Février 2010
    Messages
    553
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2010
    Messages : 553
    Points : 1 075
    Points
    1 075
    Par défaut
    Merci pour cette contribution! Je vais en avoir besoin bientot.
    +1

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur Développement Logiciel
    Inscrit en
    Septembre 2005
    Messages
    285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Côte d'Ivoire

    Informations professionnelles :
    Activité : Ingénieur Développement Logiciel
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2005
    Messages : 285
    Points : 421
    Points
    421
    Par défaut
    Merci pour cet exellent auto. Qu'en est il de la procédure inverse? Par exemple étant donnée que VariantVersJSON ajoute souvent des caractères non désirés, construire une fonction/procédure de construire du JSON.

Discussions similaires

  1. [WM18] Parser un fichier JSON (ou XML/TXT)
    Par bouillaudmartin dans le forum Windev Mobile
    Réponses: 11
    Dernier message: 10/03/2017, 17h31
  2. Parser un tableau dans un fichier JSON
    Par L'aigle de Carthage dans le forum jQuery
    Réponses: 8
    Dernier message: 25/03/2014, 16h59
  3. comment parser un fichier csv qui contient des ligne en json
    Par khadi8 dans le forum Général Python
    Réponses: 4
    Dernier message: 07/02/2014, 21h07
  4. Parser un fichier JSON en Java
    Par zinga dans le forum Android
    Réponses: 5
    Dernier message: 09/02/2011, 17h45
  5. parser un fichier html
    Par noarno dans le forum ASP
    Réponses: 2
    Dernier message: 10/12/2003, 17h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo