Malgré l’existence des fonctions JSONVersVariant et VariantVersJSON (qui ne fonctionnent pas toujours bien selon mon expérience en WD23), voici un bout de code permettant de retrouver une données dans un JSON selon son chemin.
PROCEDURE jLit(LOCAL sSourceJson est une chaîne,sCheminALire est une chaîne, sReponseSiPasTrouve est une chaîne = "", sCheminCourant est une chaîne="") nPosVirgule,nPosCrochet,nPosAccolade,nPosOuvreAccolade,n,m,nElement,nCaract sont des entiers sElement,sCode,sValeur,sSousElement sont des chaînes nPosOuvreAccolade=Position(sSourceJson,"{"+Caract(34)) TANTQUE nPosOuvreAccolade>0 sSourceJson=Milieu(sSourceJson,2) nPosVirgule=Position(sSourceJson,","+Caract(34));nPosCrochet=Position(sSourceJson,":[");nPosAccolade=Position(sSourceJson,":{") SI nPosVirgule=0 ALORS nPosVirgule=Position(sSourceJson,"}") TANTQUE nPosVirgule>0 OU nPosCrochet>0 SI nPosVirgule>0 ET ((nPosCrochet=0 OU (nPosCrochet>0 ET nPosVirgule < nPosCrochet)) ET (nPosAccolade=0 OU (nPosAccolade>0 ET nPosVirgule < nPosAccolade))) ALORS sElement=Gauche(sSourceJson,nPosVirgule-1) sCode=Remplace(ExtraitChaîne(sElement,1,":"),Caract(34),"") sValeur=Milieu(sElement,Taille(sCode)+4) //car peut contenir des : comme une adresse web, +3 car 2 guillemets+: SI Gauche(sValeur,1)=Caract(34) ALORS sValeur=Milieu(sValeur,2) SI Droite(sValeur,1)=Caract(34) ALORS sValeur=Gauche(sValeur,Taille(sValeur)-1) SI sCheminALire~=sCheminCourant+["/"]+sCode ALORS RENVOYER sValeur SINON sSourceJson=Milieu(sSourceJson,nPosVirgule+1) SINON SI nPosAccolade>0 _ET_ (nPosCrochet=0 OU (nPosCrochet>0 ET nPosAccolade < nPosCrochet)) ALORS sCode=Remplace(Gauche(sSourceJson,nPosAccolade-1),Caract(34),"") sSourceJson=Milieu(sSourceJson,nPosAccolade+1) //on trouve l'accolade de fin n=Position(sSourceJson,"}");m=Position(sSourceJson,"{");nCaract=(m>0 ET m < n) //d'autres sous-élément si { avant un } TANTQUE nCaract>0 n=Position(sSourceJson,"}",m+1);m=Position(sSourceJson,"{",m+1) SI (m>0 ET m < n) ALORS nCaract++ SINON nCaract--;m=n FIN FIN SI Position(sCheminALire,sCheminCourant+["/"]+sCode+"/")>0 ALORS RENVOYER jLit(Gauche(sSourceJson,n),sCheminALire,sReponseSiPasTrouve,sCheminCourant+["/"]+sCode) SINON sSourceJson=Milieu(sSourceJson,n+2) FIN SINON SI nPosCrochet>0 ALORS sCode=Remplace(Gauche(sSourceJson,nPosCrochet-1),Caract(34),"") sSourceJson=Milieu(sSourceJson,nPosCrochet+1) //on trouve le crochet de fin n=Position(sSourceJson,"]");m=Position(sSourceJson,"[");nCaract=(m>0 ET m < n) //d'autres sous-élément si { avant un } TANTQUE nCaract>0 n=Position(sSourceJson,"]",m+1);m=Position(sSourceJson,"[",m+1) SI (m>0 ET m < n) ALORS nCaract++ SINON nCaract--;m=n FIN FIN SI Position(sCheminALire,sCheminCourant+["/"]+sCode+"[")>0 ALORS SI n>0 ET (n < =m OU m=0) ALORS sSousElement=Milieu(sSourceJson,2,n-2);nElement=0 SINON SI n=0 ALORS n=Position(sSourceJson,"}");m=Position(sSourceJson,"{");nCaract=(m>0 ET m < n) //d'autres sous-élément si { avant un } TANTQUE nCaract>0 n=Position(sSourceJson,"}",m+1);m=Position(sSourceJson,"{",m+1) SI (m>0 ET m < n) ALORS nCaract++ SINON nCaract--;m=n FIN FIN sSousElement=Gauche(sSourceJson,n) SINON //problème, on a pas trouvé le crochet de fin RENVOYER sReponseSiPasTrouve FIN BOUCLE m=Position(sSousElement,"{") SI m>0 ALORS nElement++;m=1 n=Position(sSousElement,"}",m+1);m=Position(sSousElement,"{",m+1) SI m>0 _ET_ m < n ALORS nCaract=1 TANTQUE nCaract < >-1 n=Position(sSousElement,"}",m+1);m=Position(sSousElement,"{",m+1) SI (m>0 ET m < n) ALORS nCaract++ SINON nCaract--;m=n FIN FIN FIN SI n>0 ALORS SI Position(sCheminALire,sCheminCourant+["/"]+sCode+"["+nElement+"]")>0 ALORS RENVOYER jLit(Gauche(sSousElement,n),sCheminALire,sReponseSiPasTrouve,sCheminCourant+["/"]+sCode+"["+nElement+"]") FIN sSousElement=Milieu(sSousElement,n+2) //+2 correspond au }, SINON SORTIR FIN SINON POUR TOUTE CHAÎNE sValeur DE sSousElement SEPAREE PAR Caract(34)+","+Caract(34) nElement++ SI Position(sCheminALire,sCheminCourant+["/"]+sCode+"["+nElement+"]")>0 ALORS RENVOYER Remplace(sValeur,Caract(34),"") FIN RENVOYER sReponseSiPasTrouve FIN FIN SINON sSourceJson=Milieu(sSourceJson,n+2) FIN FIN nPosVirgule=Position(sSourceJson,","+Caract(34));nPosCrochet=Position(sSourceJson,":[");nPosAccolade=Position(sSourceJson,":{") SI nPosVirgule=0 ALORS nPosVirgule=Position(sSourceJson,"}") //pour la dernière accolade FIN nPosOuvreAccolade=Position(sSourceJson,"{"+Caract(34),nPosOuvreAccolade) FIN RENVOYER sReponseSiPasTrouve
Son usage est très simple : il suffit de donner le chemin de la donnée pour avoir son résultat. Exemple jLit(sResHTML, »client/commande[1]/numero »).
Les paramètres :
sSourceJson : le résultat que vous avez obtenu en faisant une requête (typiquement, le contenu de HTTPDonneRésultat(httpRésultat))
sCheminALire : voir exemple ci-dessus. Le « [1] » correspond à la première commande, mettre donc « [2] » pour la seconde commande et ainsi de suite. S’il n’y a pas d’occurrence, juste enlever le chiffre entre crochet : jLit(sResHTML, »client/commande/numero »)
sRéponseSiPasTrouvé : ce que renvoie la fonction si la valeur du chemin n’a pas été trouvé (car elle n’existe pas ou est indéxée ou …)
sCheminCourant : chemin qui est passé lors d’une seconde lecture de la procédure (elle est récursive) > ne pas renseigner lors de l’appel.