24.09.2019, Vladimír Klaus, navštíveno 3261x
Při získávání dat z webů nebo webových služeb můžete často volit mezi XML nebo JSON. Díky velmi pěkné implementaci JSON v Delphi je možné data získávat pohodlně. Navíc zápis je velmi příjemný a pokud víte, co a kde hledáte, pak se k údaji dostanete opravdu velmi rychle.
Mějme například takovýto JSON text. Je to reálný příklad, protože přesně toto dostanete ze služeb Google Maps Platform, jako jsou Directions, Distance Matrix apod.
{
"destination_addresses" : [ "Jičíněves, Czechia" ],
"origin_addresses" : [ "Terezínská 701/4, 190 00 Praha-Letňany, Czechia" ],
"rows" : [
{
"elements" : [
{
"distance" : {
"text" : "85.5 km",
"value" : 85467
},
"duration" : {
"text" : "1 hour 30 mins",
"value" : 5427
},
"status" : "OK"
}
]
}
],
"status" : "OK"
}
Předpokládejme (pro jednoduchost), že potřebujete pouze zjistit vzdálenost. Z výše uvedeného víte jak přesně JSON soubor (obecně text) vypadá a že tedy můžete jít na jisto. Samozřejmě je vhodné vše před přístupem ověřovat, protože si nemůžete být nikdy jisti, že formát a hodnoty budou vypadat přesně tak, jako v době, kdy to programujete.
Obrovskou výhodou tohoto jednoduchého příkladu je přímý přístup k daným datům pomocí tečkové notace.
uses JSON;
procedure ZpracujJsonDistanceMatrix(aJsonText: string);
var
jv, jv2: TJSONValue;
s: string;
r: double;
begin
//jv je vlastně root celého JSONu
jv:=TJSONObject.ParseJSONValue(aJsonText);
try
if jv<>nil then begin
jv2:=jv.FindValue('status'); //v rootu, ne někde zanořený
if jv2<>nil then begin
s:=jv2.Value;
if s='OK' then begin
//z rootu hledám přesně tuto cestu
jv2:=jv.FindValue('rows[0].elements[0].distance.text');
if jv2<>nil then begin
s:=jv2.Value;
s:=StringReplace(s, 'km', '', [rfIgnoreCase]);
s:=StringReplace(s, '.', ',', []);
//získám vzdálenost v kilometrech a jako reálné číslo
if TryStrToFloat(s, r) then . . .
end;
end;
end;
end;
finally
FreeAndNil(jv);
end;
end;
Pokud by JSON obsahoval více údajů, pak se už musí pracovat s poli (TJSONArray) a vše je nepatrně složitější.
procedure ZpracujJsonDirections(aJsonText: string);
var
jv, jv2, jv3: TJSONValue;
jarr: TJSONArray;
s: string;
r: double;
i: integer;
begin
jv:=TJSONObject.ParseJSONValue(aJsonText);
try
if jv<>nil then begin
jv2:=jv.FindValue('status');
if jv2<>nil then begin
s:=jv2.Value;
if s='OK' then begin
//z rootu hledám sadu cest
jarr:=jv.FindValue('routes') as TJSONArray;
if jarr<>nil then begin
for i:=0 to jarr.Count-1 do begin
jv3:=jarr.Items[i].FindValue('legs[0].distance.text');
if jv3<>nil then begin
s:=jv3.Value;
s:=StringReplace(s, 'km', '', [rfIgnoreCase]);
s:=StringReplace(s, '.', ',', []);
if TryStrToFloat(s, r) then . . .
end;
end;
end;
end;
end;
end;
finally
FreeAndNil(jv);
end;
end;
Zdroje: