Page 1 sur 1

Difficultés avec JSON !

Publié : mar. 04/févr./2020 11:26
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" ???

Re: Difficultés avec JSON !

Publié : mar. 04/févr./2020 11:54
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:

Re: Difficultés avec JSON !

Publié : mar. 04/févr./2020 13:02
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

Re: Difficultés avec JSON !

Publié : mar. 04/févr./2020 13:25
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 ?

Re: Difficultés avec JSON !

Publié : mar. 04/févr./2020 15:55
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.