JSON reading

Despite the existence of functions JSONToVariant and VariantToJSON (which do not always work well according to my experience in WD23), here is a piece of code to find a data in a JSON according to its path. Useful also for WinDev 18 and earlier.

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

Its use is very simple: it is enough to give the path of the data to have its result. Example jLit(sResHTML,”client/commande[1]/numero”).

Parameters :
sSourceJson : the result you obtained by querying (typically, the content of HTTPGetResult(httpResult))
sCheminALire : see example above. The “[1]” is the first command, so put “[2]” for the second command, and so on. If there is no occurrence, just remove the number between hook : jLit(sResHTML,”client/commande/numero”)
sRéponseSiPasTrouvé : what the function returns if the value of the path was not found (because it does not exist or is indexed or …)
sCheminCourant : path that is passed during a second read of the procedure (it is recursive)> do not fill in the call

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.