Italian community of Lazarus and Free Pascal

Programmazione => Lazarus e il web => Topic aperto da: CieloInvernale - Dicembre 19, 2016, 10:53:02 pm

Titolo: Recupero e parsing di dati JSON dalle OpenWeatherMaps
Inserito da: CieloInvernale - Dicembre 19, 2016, 10:53:02 pm
Sto cercando di interfacciarmi con le OpenWeaterMaps API (http://openweathermap.org/). Le API sono chiare, ho qualche problema lato Lazarus....

Il mio scopo è semplice: recuperare i dati JSON dall'URL appropriato e quindi fare il parsing di alcuni nodi sotto forma di semplici stringhe.

Il mio programma fonora cerca di ottenere il valore di "main" ("Clouds" nell'esempio che segue - notate che ci sono due differenti nodi "main" nella risposta della API, sto cercando di accedere il primo nidificato dentro "weather" o, in altri termini "weather->main:Clouds").

Esempio della API response:

Codice: [Seleziona]
{"coord":
{"lon":145.77,"lat":-16.92},
"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],
"base":"cmc stations",
"main":{"temp":293.25,"pressure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37},
"wind":{"speed":5.1,"deg":150},
"clouds":{"all":75},
"rain":{"3h":3},
"dt":1435658272,
"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunrise":1435610796,"sunset":1435650870},
"id":2172797,
"name":"Cairns",
"cod":200}

Il mio codice finora (MYCITYID e MYAPPID sono segnaposto per i valori reali, che ovviamente non pubblico...):

Codice: [Seleziona]
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, fphttpclient,
  fpjson, jsonparser;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
  jData : TJSONData;
  jObject : TJSONObject;
  wheater_main : String;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
 
procedure TForm1.FormCreate(Sender: TObject);
begin
  jData := GetJSON(TFPHTTPClient.SimpleGet('http://api.openweathermap.org/data/2.5/weather?id=MYCITYID&appid=MYAPPID'));
 
  wheater_main := jData.FindPath('main').AsString;
 
  Memo1.Lines.Clear;
 
  Memo1.Lines.Add(wheater_main);
 
end;
 
end.

Il codice compila correttamente e produce un eseguibile, ma quando tento di lanciarlo appare il seguente errore:

Cannot convert data from object value.

Qualche idea su cosa non funzioni? Temo che sia il parsing....

Grazie in anticipo per il vostro tempo e la vostra attenzione.
Titolo: Re:Recupero e parsing di dati JSON dalle OpenWeatherMaps
Inserito da: nomorelogic - Dicembre 20, 2016, 12:19:40 am
ciao CieloInvernale
"weather" è un array, anche se contiene un solo oggetto (di cui "main" è una delle proprietà).
Per questo devi prima identificare quale elemento dell'array vuoi usare per leggere il valore di "main".
Prova il codice quì sotto.

Codice: [Seleziona]
procedure TForm1.FormCreate(Sender: TObject);
var jData : TJSONData;
    jObject : TJSONObject;
    jObject2 : TJSONObject;
begin
  jData:=GetJSON(
      '{"coord": ' +
      '{"lon":145.77,"lat":-16.92}, ' +
      '"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}], ' +
      '"base":"cmc stations", ' +
      '"main":{"temp":293.25,"pressure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37}, ' +
      '"wind":{"speed":5.1,"deg":150}, ' +
      '"clouds":{"all":75}, ' +
      '"rain":{"3h":3}, ' +
      '"dt":1435658272, ' +
      '"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunrise":1435610796,"sunset":1435650870}, ' +
      '"id":2172797, ' +
      '"name":"Cairns", ' +
      '"cod":200} '
    );

  jObject := TJSONObject(jData.FindPath('weather'));
  jObject2 := TJSONObject(jObject.Extract(0));

  wheater_main := jObject2.FindPath('main').AsJSON;

  Memo1.Clear;
  Memo1.Lines.Add(wheater_main);

end;

nomorelogic


Edit:
per info su come gestire XML e JSON, puoi vedere questo documento
http://www.freepascal.org/~michael/articles/webdata/webdata.pdf (http://www.freepascal.org/~michael/articles/webdata/webdata.pdf)


Edit2:
per completezza, riporto il link sullo stesso quesito sul forum ufficiale
http://forum.lazarus-ide.org/index.php/topic,35183.msg232259/topicseen.html#new (http://forum.lazarus-ide.org/index.php/topic,35183.msg232259/topicseen.html#new)