Difficultés avec JSON !

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
PhM
Messages : 118
Inscription : dim. 08/déc./2019 10:50

Difficultés avec JSON !

Message par PhM »

Bonjour,

Un nouveau problème :

Je souhaite récupérer sur un serveur ouvert (API) un fichier au format json en conservant sa structure pour faire des tris ensuite.

Lorsque vous mettez dans votre navigateur : https://api.flightplandatabase.com/nav/airport/LFKC
Ce serveur vous retourne immédiatement (extrait) au format json avec sa structure json ?

Code : Tout sélectionner

<response>
<airport>
<ICAO>LFKC</ICAO>
<IATA>CLY</IATA>
<name>St Catherine</name>
<regionName>France</regionName>
<elevation>208.00000031616003</elevation>
<lat>42.5308</lat>
<lon>8.79298</lon>
<magneticVariation>2.57476996741889</magneticVariation>
<timezone>
<name>Europe/Paris</name>
<offset>3600</offset>
</timezone>
<times>
<sunrise>2020-02-04T06:37:45.983Z</sunrise>
<sunset>2020-02-04T16:42:10.496Z</sunset>
<dawn>2020-02-04T06:08:03.044Z</dawn>
<dusk>2020-02-04T17:11:53.435Z</dusk>
</times>
<runwayCount>1</runwayCount>
<runways>
<runway>
<ident>18</ident>
<width>131.233596</width>
<length>7585.990825179</length>
<bearing>179.814</bearing>
<surface>CONCRETE</surface>
<markings>
<marking>APP</marking>
</markings>
...
Avec ce programme, j'essaie d'enregistrer le fichier json mais mon résultat est un fichier ne comprenant plus sa structure ?

Code : Tout sélectionner

 InitNetwork()
  
  Source_File$ = "LFKC.json"
  
  ReceiveHTTPFile("https://api.flightplandatabase.com/nav/airport/LFKC", Source_File$)
  
  If Not OpenFile(0, Source_File$)
    MessageRequester("Erreur","Echec")
    End
  EndIf
  
  While Not Eof(0)
    Txt$ = ReadString(0, #PB_UTF8)
  Wend
  
;=============================================================================================

  If ReadFile(0, Source_File$)
    Txt$ = ReadString(0, #PB_UTF8)      ; une seule ligne à lire dans le fichier !
    CloseFile(0)
  EndIf

  Txt$ = Txt$ + ","  ; Ajout d'une virgule à la fin du fichier pour voir la ligne TAF
  
Dim L$(5000)
z = 1

For x = 0 To Len(Txt$)
  
  line$ = line$ + Mid(Txt$,x,1)
   
  If Mid(Txt$,x,1) = ","
    
    line$ = ReplaceString(line$, ",", "")
    line$ = ReplaceString(line$, "{", "")
    line$ = ReplaceString(line$, "}", "")
    line$ = ReplaceString(line$, "]", "")
    line$ = ReplaceString(line$, "[", "")
    line$ = ReplaceString(line$, Chr(34), "")
    
    ;Debug line$ ; Lecture des lignes complétes avec entêtes
    
    L$(z) = line$
    z = z + 1
    line$ = ""
    
  EndIf
Next

; Enregistrement des lignes décodées et nettoyées
DeleteFile(Source_File$)

ReDim L$(z-1)
If OpenFile(0,Source_File$)
  GetCurrentDirectory()
  For zz = 1 To z - 1
      WriteStringN(0,L$(zz)) 
  Next
EndIf

CloseFile(0)
Comprenez-vous ce qui "cloche" ???
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Difficultés avec JSON !

Message par Marc56 »

PhM a écrit : Je souhaite récupérer sur un serveur ouvert (API) un fichier au format json en conservant sa structure pour faire des tris ensuite.
Avec HttpRequest tu charges tout le fichier puis avec ParseJSON il entre dans une structure.

Code : Tout sélectionner

InitNetwork()

URL$ = "https://api.flightplandatabase.com/nav/airport/LFKC"

HttpRequest = HTTPRequest(#PB_HTTP_Get, URL$)

If HttpRequest
    Status$ = HTTPInfo(HTTPRequest, #PB_HTTP_StatusCode)
    Infos$  = HTTPInfo(HTTPRequest, #PB_HTTP_Response)
    FinishHTTP(HTTPRequest)
    
    ParseJSON(0, Infos$)
        
    Debug ComposeJSON(0, #PB_JSON_PrettyPrint)
Else
    Debug "Request creation failed"
EndIf

Code : Tout sélectionner

{
  "times"            : {
      "dusk"   : "2020-02-04T17:11:53.435Z",
      "sunrise": "2020-02-04T06:37:45.983Z",
      "sunset" : "2020-02-04T16:42:10.496Z",
      "dawn"   : "2020-02-04T06:08:03.044Z"
    },
  "ICAO"             : "LFKC",
  "runways"          : [
      {
        "bearing"        : 179.814,
        "ends"           : [
[...]
Le fichier que tu as donné est reformaté en XML.
Le site indique que les fichiers peuvent parfois être en XML ou JSON.
Si on veut à coup sûr du JSON, il faut le préciser.
The response format and API version are specified using the Accept request header to choose a media type. The allowed values are in the table below. If you do not specify a API version in your request, you will be served the latest version, which may differ from the expected format or content. Therefore, it is recommended that you always specify an API version using the correct media type when making a request. If no recognized media type is requested, the server will return JSON formatted data.
https://flightplandatabase.com/dev/api

:wink:
Avatar de l’utilisateur
PhM
Messages : 118
Inscription : dim. 08/déc./2019 10:50

Re: Difficultés avec JSON !

Message par PhM »

Merci beaucoup Marc !
Décidément, tu réponds souvent positivement à mes sollicitations de "débutant en progression" !
C'est par fais comme résultat pour m'y retrouver un peu.
Philippe
Avatar de l’utilisateur
PhM
Messages : 118
Inscription : dim. 08/déc./2019 10:50

Re: Difficultés avec JSON !

Message par PhM »

C'est curieux, il manque le début du fichier chargé par ton code ?

Normalement, le début est :

Code : Tout sélectionner

<response>
<airport>
<ICAO>LFMT</ICAO>
<IATA>MPL</IATA>
<name>Montpellier/Mediterranee</name>
<regionName>France</regionName>
<elevation>17.000000025840002</elevation>
<lat>43.5762</lat>
<lon>3.96325</lon>
<magneticVariation>1.4960132348713595</magneticVariation>
<timezone>
<name>Europe/Paris</name>
<offset>3600</offset>
</timezone>
<times>
<sunrise>2020-02-04T06:59:22.237Z</sunrise>
<sunset>2020-02-04T16:59:12.699Z</sunset>
<dawn>2020-02-04T06:29:05.553Z</dawn>
<dusk>2020-02-04T17:29:29.383Z</dusk>
</times>
<runwayCount>2</runwayCount>
<runways>
...
Et, avec ton code, le début donne :

Code : Tout sélectionner

{
  "times"            : {
      "dusk"   : "2020-02-04T17:29:29.383Z",
      "sunrise": "2020-02-04T06:59:22.237Z",
      "sunset" : "2020-02-04T16:59:12.699Z",
      "dawn"   : "2020-02-04T06:29:05.553Z"
    },
  "ICAO"             : "LFMT",
  "runways"          : [
      {
        "bearing"        : 124.832,
        "ends"           : [
            {
              "lon"  : 3.95574,
              "ident": "12L",
              "lat"  : 43.5861
            },
            {
              "lon"  : 43.5727,
              "ident": "30R",
              "lat"  : 43.5861
            }
          ],
        "navaids"        : [],
        "overrunLength"  : 0,
        "length"         : 8539.009199,
        "width"          : 164.041995,
        "lighting"       : [
            "CENTERLINE",
            "EDGE",
            "THRESHOLD"
          ],
        "surface"        : "ASPHALT",
        "ident"          : "12L",
        "thresholdOffset": 0,
        "markings"       : [
...
En fait, les données semblent en partie absentes et mélangées par rapport à la réponse directe depuis un navigateur ?
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Difficultés avec JSON !

Message par Marc56 »

Le fichier tel que tu l'ouvres dans un navigateur est interprété comme du XML, ce qu'il indique par le message suivant
Aucune information de style ne semble associée à ce fichier XML. L’arbre du document est affiché ci-dessous.

Si tu regarde le code source (pas dans le navigateur, mais le fichier téléchargé) il se présente même comme ceci

Code : Tout sélectionner

ICAO:LFKC
IATA:CLY
name:St Catherine
regionName:France
elevation:208.00000031616003
lat:42.5308
lon:8.79298
magneticVariation:2.5748219837535404
timezone:name:Europe/Paris
offset:3600
times:sunrise:2020-02-04T06:37:45.983Z
sunset:2020-02-04T16:42:10.496Z
dawn:2020-02-04T06:08:03.044Z
dusk:2020-02-04T17:11:53.435Z
runwayCount:1
[...]
On pourrait le traiter avec la lib des fichiers INI en replaçant les : par des = mais ce n'est pas si simple à cause des répétitions

Le format JSON ne stocke pas les données dans l'ordre de lecture et il hiérarchise.
Tu va trouver par exemple
"ICAO" : "LFKC",
Il faut ensuite utiliser les outils JSON manipuler ces clé.

On pourrait penser qu'il est plus facile de l'utiliser en mode texte ou XML, mais si par exemple tu regardes
frequency
Ça donne ça:

Code : Tout sélectionner

<frequencies>
<frequency>
<type>TWR</type>
<frequency>123200000</frequency>
<name>Calvi Tower</name>
</frequency>
<frequency>
<type>APP</type>
<frequency>123820000</frequency>
<name>Basti Approach</name>
</frequency>
<frequency>
<type>GND</type>
<frequency>121700000</frequency>
<name>Calvi Ground</name>
</frequency>
<frequency>
<type>REC</type>
<frequency>131170000</frequency>
<name>Calvi ATIS</name>
</frequency>
</frequencies>
(On peut voir mieux en utilisant un outils de formatage)
En traitant le fichier comme du texte brut, ça devient difficile.
Alors qu'en JSON, ça donne ça

Code : Tout sélectionner

 "frequencies"      : [
      {
        "name"     : "Basti Approach",
        "type"     : "APP",
        "frequency": 123820000
      },
      {
        "name"     : "Calvi Ground",
        "type"     : "GND",
        "frequency": 121700000
      },
      {
        "name"     : "Calvi ATIS",
        "type"     : "REC",
        "frequency": 131170000
      },
      {
        "name"     : "Calvi Tower",
        "type"     : "TWR",
        "frequency": 123200000
      }
    ],
Dans les trois cas il faudrait donc faire des boucles par exemple pour toutes les fréquences.
ComposeJSON(0, #PB_JSON_PrettyPrint) se contente de donner une représentation à titre d'information tout comme on peut le faire avec:
ShowLibraryViewer("JSON", 0)

PB peut traiter les deux formats XML et JSON donc tu peux choisir.
Répondre