Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
Delphi 12 Athens
|
AW: JSON einlesen - Hilfe für Anfänger
23. Dez 2021, 11:19
Ich hatte etwas Muße das nochmal detaillierter zu betrachten. Herausgekommen ist dabei eine hybride Lösung:
Delphi-Quellcode:
unit TestJSON1Unit1;
interface
uses
System.SysUtils, System.Classes, System.Generics.Collections,
REST.JSON.Types, REST.Json, System.JSON;
type
TEPGInfo = class
private
FId: Integer;
[JSONName(' t')]
FTitle: string;
[JSONName(' et')]
FEpisode_Title: string;
[JSONName(' g')]
FGenre: TArray< string>;
public
property Id: Integer read FId;
property Title: string read FTitle;
property Episode_Title: string read FEpisode_Title;
property Genre: TArray< string> read FGenre;
end;
type
TChannel = class(TObjectList<TEPGInfo>)
private
FName: string;
public
property Name: string read FName write FName;
end;
TChannels = class(TObjectDictionary< string, TChannel>);
procedure LoadChannels( const AJson: string; Target: TChannels; const AChannels: TArray< string> = nil);
implementation
uses
System.StrUtils;
procedure LoadChannels( const AJson: string; Target: TChannels; const AChannels: TArray< string> = nil);
var
channel: TChannel;
channelName: string;
item: TJSONValue;
jsonObj: TJSONObject;
jsonValue: TJSONValue;
pair: TJSONPair;
begin
jsonValue := TJSONObject.ParseJSONValue(AJson);
try
jsonObj := (jsonValue as TJSONObject).Values[' channels'] as TJSONObject;
for pair in jsonObj do begin
channelName := pair.JsonString.Value;
if (Length(AChannels) > 0) and not MatchText(channelName, AChannels) then Continue;
channel := TChannel.Create;
channel. Name := channelName;
for item in (pair.JsonValue as TJSONArray) do
channel.Add(TJson.JsonToObject<TEPGInfo>(item as TJSONObject));
Target.Add(channel. Name, channel);
end;
finally
jsonValue.Free;
end;
end;
end.
Aufgerufen wird das dann so:
Delphi-Quellcode:
program TestJSON1;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.IOUtils,
System.Generics.Collections,
TestJSON1Unit1 in ' TestJSON1Unit1.pas';
procedure ListChannels(Channels: TChannels);
{ Sender auflisten }
var
arr: TArray< string>;
S: string;
begin
arr := Channels.Keys.ToArray;
TArray.Sort< string>(arr);
for S in arr do
Writeln(S);
end;
procedure ListProgram(Channels: TChannels; const AName: string);
{ Programm auflisten }
var
channel: TChannel;
info: TEPGInfo;
begin
channel := Channels[AName];
if channel <> nil then begin
Writeln(channel. Name);
for info in channel do
Writeln(Format(' %d: %s - %s (%s)', [info.Id, info.title, info.Episode_Title, string.Join(' ,', info.Genre)]));
end;
end;
procedure ParseJson();
var
arr: TArray< string>;
channel: TChannel;
channels: TChannels;
FileContent: string;
info: TEPGInfo;
S: string;
begin
FileContent := TFile.ReadAllText(' c:\Users\Uwe\Downloads\EPG_GUIDE\EPG_GUIDE.json');
channels := TChannels.Create;
try
LoadChannels(FileContent, channels, [' ard', ' zdf']);
ListChannels(channels);
ListProgram(channels, ' ard');
ListProgram(channels, ' zdf');
finally
channels.Free;
end;
end;
begin
try
ParseJson;
except
on E: Exception do
Writeln(E.ClassName, ' : ', E. Message);
end;
Write(' press enter...');
Readln;
end.
Sollten weitere EPG-Felder benötigt werden, reicht es diese in der Klasse TEPGInfo entsprechend zu ergänzen.
|
|
Zitat
|