Lecture JSON

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. Utile aussi pour WinDev 18 et antérieur.

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.

Ce site n'a aucun lien avec la société PC SOFT®. Les marques "WinDev" et "WebDev" sont des marques déposées de la société PC SOFT.