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 sReponseSiPasTrouveSon 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.