Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi JSON einlesen - Hilfe für Anfänger (https://www.delphipraxis.net/209555-json-einlesen-hilfe-fuer-anfaenger.html)

mytbo 21. Dez 2021 14:34

AW: JSON einlesen - Hilfe für Anfänger
 
Zitat:

Zitat von TERWI (Beitrag 1499452)
Mit Denkanstoß mente ich ein paar hilfreiche Zeilen Code.

Du bist zu unspezifisch. Es fängt damit an, dass du noch nicht geschrieben hast, ob du an Delphi Bordmittel gebunden bist, oder auch andere Libraries einsetzen kannst. Als Startpunkt für mORMot(1) mal dieser Sourcecode. Der gesamte Thread enthält noch mehr Beispiele.

Bis bald...
Thomas

venice2 21. Dez 2021 14:36

AW: JSON einlesen - Hilfe für Anfänger
 
Delphi-Quellcode:
function TZattoo.FormatJSONStr(AString: string): string;
var
  Obj: TJsonObject;
begin

  Obj := Obj.Parse(PWideChar(AString))as TJsonObject;
  result := Obj.ToJSON(False);
end;
Delphi-Quellcode:
procedure TZattoo.GetEPG;
var
  iRun, nRun: Integer;
  doc: TDocVariantData;
  docChannels: PDocVariantData;
  docPrograms: PDocVariantData;

  TimeEnd  : Int64;
  TimeSTart : Int64;
  SendStr  : string;
  Data     : string;
  TxtFile: string;
  dwBytes: DWORD;
  lstream: TFileStream;
  lutf8: UTF8String;
  List : TStringList;
begin

  SetLength(gEPG, 0);
  SetLength(gEpgChannels, 0);

  try
    TimeStart := DateTimeToUnix(IncHour(Now, 0), false);
    TimeEnd := DateTimeToUnix(IncDay(Now, 1), false);
    SendStr := FProvRec.URL +
      cPathEPG +
      FProvRec.PWRHASH +
      '?end=' + inttostr(TimeEnd) +
      '&start=' + inttostr(TimeStart) +
      '&format=json' + '&details=True';

    Log('GetEPG:', 'SendStr: ' + Sendstr);
    data := FHTTP.Get(SendStr);
  except
    Log('GetEPG:', 'Failed !');
    exit;
  end;

  TxtFile := ExtractFilePath(ParamStr(0)) + 'Json\EPG_data.json';
  if FileExists(TxtFile) then
    DeleteFile(TxtFile);

  List := TStringList.Create;
  try
    List.Clear;
    List.Append(Data);
    List.SaveToFile(TxtFile);
  finally
    List.Free;
  end;

  lstream := TFileStream.create(TxtFile, fmOpenReadWrite);
  try
    dwBytes := lstream.size;
    Setlength(lutf8, dwBytes);
    lstream.ReadBuffer(lutf8[1], dwBytes);
    // Format Json
    lutf8 := UTF8String(FormatJSONStr(string(lutf8)));
    lstream.Position := 0;
    lstream.WriteBuffer(lutf8[1], length(lutf8));
  finally
    lstream.free;
  end;

  nRun := 0;

  doc.InitJSONFromFile(TxtFile, JSON_OPTIONS_FAST_EXTENDED);
  if not doc.B['success'] then
    Exit;
  try
  for iRun := 0 to doc.A['channels'].Count - 1 do
  begin
    docChannels := doc.A['channels']._[iRun];
    setLength(gEpgChannels, iRun + 1);
    gEpgChannels[iRun] := docChannels.S['cid'];

    docPrograms := docChannels.A['programs']._[nRun];
    setLength(gEpg, iRun + 1);
    setLength(sStart, iRun + 1);
    setLength(SEnd, iRun + 1);

    Log('GetEPG: Current Channel = ', IntToStr(iRun) + ' ' + gEpgChannels[iRun]);
    // Image Url
    gEpg[iRun].i_url := docPrograms.S['i_url'];
    Log('GetEPG: Image Url = ', gEpg[iRun].i_url);
    // Stop Zeit
    gEpg[iRun].e := docPrograms.I['e'];
    if gEpg[iRun].e <> 0 then
      SEnd[iRun] := UnixToDateTime(gEpg[iRun].e, false)
    else
    SEnd[iRun] := 0;
    Log('GetEPG: Stop Time = ', IntToStr(gEpg[iRun].e));

    // Genre
    gEpg[iRun].g := StringReplace(docPrograms.S['g'], '[', '', [rfReplaceAll]);
    gEpg[iRun].g := StringReplace(gEpg[iRun].g, ']', '', [rfReplaceAll]);
    gEpg[iRun].g := StringReplace(gEpg[iRun].g, '"', '', [rfReplaceAll]);
    if gEpg[iRun].g = '' then
      gEpg[iRun].g := 'N/A';
    Log('GetEPG: Genre = ', gEpg[iRun].g);

    gEpg[iRun].ry_u := docPrograms.I['ry_u'];
    gEpg[iRun].i := docPrograms.S['i'];
    gEpg[iRun].sr_u := docPrograms.I['sr_u'];
    gEpg[iRun].c := docPrograms.S['c'];
    gEpg[iRun].r_e:= docPrograms.B['r_e'];
    gEpg[iRun].e_no:= docPrograms.S['e_no'];
    // Start Zeit
    gEpg[iRun].s:= docPrograms.I['s'];
    if gEpg[iRun].s <> 0 then
      sStart[iRun] := UnixToDateTime(gEpg[iRun].s, false)
    else
    sStart[iRun] := 0;
    Log('GetEPG: Start Time = ', IntToStr(gEpg[iRun].s));

    // Titel
    gEpg[iRun].t:= docPrograms.S['t'];
    Log('GetEPG: Title = ', gEpg[iRun].t);
    gEpg[iRun].ser_e:= docPrograms.B['ser_e'];
    gEpg[iRun].c_ids := docPrograms.I['c_ids'];
    // Unter Titel
    gEpg[iRun].et := docPrograms.S['et'];
    if gEpg[iRun].et = '' then
      gEpg[iRun].et := 'N/A';
    gEpg[iRun].i_t := docPrograms.S['i_t'];
    gEpg[iRun].ts_id := docPrograms.I['ts_id'];
    gEpg[iRun].id := docPrograms.I['id'];
    gEpg[iRun].tms_id := docPrograms.s['tms_id'];
    gEpg[iRun].s_no := docPrograms.I['s_no'];
  end;
  except
    on e: exception do
      Log('GetEPG:', 'Failed! with Message ' + e.Message);
  end;
end;
Wie @mytbo schon sagt verwende dazu mORMot
Ich selber mache mit Zattoo nichts mehr es nervt wenn alle paar Tage die API wieder geändert wird.
Zudem gibt es diese ja auch nicht wirklich.

TERWI 21. Dez 2021 14:51

AW: JSON einlesen - Hilfe für Anfänger
 
wieder gelöscht...

TERWI 21. Dez 2021 15:10

AW: JSON einlesen - Hilfe für Anfänger
 
Wie ich schon sagte: ... ja es gibt reichlich ....
Aber ich sehe irgendwie den Wald vor lauter JSON nicht mehr.
Ich bekomme eben noch ein JSON-Objekt aus dem String hin.
Aber wie "extrahiere" ich daraus das Array mit einer Loop ?
Und wie lese ich die Namen der Einträge (ohne Wert ?) ?
Ein kleiner 5-Zeiler oder so wäre hilfreicher als Verweise auf Libraries und Ableitungen daraus.
Oft hilft ein funktionierendes Beispiel mehr als stundenlang rumlesen (und nicht verstehen).

Ob mit Bordmitteln oder extra Lib ist eigentlich egal - einfach sollte es sein.
Beispile zu den Libs hin und/oder her: Wenn man JSON als solches nicht wirklich versteht... (weil noch nie bedarf gehabt, das verstehen zu müssen)
Siehe erster Absatz.

@venice2
Danke dir für deinen Source zum Aulesen von ZATTOO-V2.
Funzt leider nicht mehr, weil Aufbau der Daten anders.
So was in der Art hatte ich mir auch schon selbst gebastelt.

venice2 21. Dez 2021 15:16

AW: JSON einlesen - Hilfe für Anfänger
 
Zitat:

Danke dir für deinen Source zum Aulesen von ZATTOO-V2.
Funzt leider nicht mehr, weil Aufbau der Daten anders.
So was in der Art hatte ich mir auch schon selbst gebastelt.
Der Source liest nicht Zattoo v2 ein sondern verarbeitet die Json Datei TxtFile EPG_data.json
Das ist was du wolltest. ;)

Mehr wirst du hier wohl nicht bekommen.

TERWI 21. Dez 2021 15:49

AW: JSON einlesen - Hilfe für Anfänger
 
Grins. Kann es sein, das der Ursprung von mir stammt ?
Liest sich im großen und ganzen wie meine Zat-Lib ... 8-)
Mein Proggie läufz ganz nett - nur leider noch ohne vollständige EPG-Übersicht.

Mit Zatto-V2 meine ich auch die Datenversion, die man von Zattoo (hier EWE-Tel) lädt.
Mittlerweile ist es V3 und das geht eben anders. Sie 1. Posting / mein Datenanhang ein paar Post weiter vorne.

Ja, ich habs gesehen das du da eine Datei einliest - ich gebe den Daten-String direkt von HTTP.Get

Ich möchte ja auch keine spezielle Hilfe beim Auseinanderbröseln von Zattoo-Daten, sondern lediglich diesen JSON String (oder auch den der Channels, EPG-Details, ....)

venice2 21. Dez 2021 16:05

AW: JSON einlesen - Hilfe für Anfänger
 
Zitat:

Grins. Kann es sein, das der Ursprung von mir stammt ?
Klar stammt der von dir hast ihn mir doch geschickt.

Destotrotz arbeite ich mit dem parsen der *.json und nicht wie du alles von Hand -> Auseinandergebröselt. Pos, PosEx und Konsorte.
In meiner Pas befindet sich minimalistischer Code von dir da ich hier mit Json arbeite und nicht so wie du mit wie schon gesagt PosNext, Pos, PosEx.

Zitat:

Ich möchte ja auch keine spezielle Hilfe beim Auseinanderbröseln von Zattoo-Daten, sondern lediglich diesen JSON String (oder auch den der Channels, EPG-Details, ....)
Ach...
Schau dir doch den Source an da wird nix Auseinandergebröselt sondern der Json string geparst.
Wenn du das nicht erkennst sorry dann kann ich dir da auch nicht weiter helfen.

Viel spaß noch damit.
Bin raus da mich Zattoo nicht wirklich noch irgendwie interessiert.

Aviator 21. Dez 2021 17:02

AW: JSON einlesen - Hilfe für Anfänger
 
Also ich weiß nicht was man da sonst noch zu schreiben soll. Ich habe dir doch auch schon ein Beispiel gemacht. Oder hast du das etwa komplett überlesen?

Uwe Raabe 21. Dez 2021 17:33

AW: JSON einlesen - Hilfe für Anfänger
 
Zitat:

Zitat von Aviator (Beitrag 1499502)
Also ich weiß nicht was man da sonst noch zu schreiben soll. Ich habe dir doch auch schon ein Beispiel gemacht.

Das compiliert aber so nicht. Wenn man sich damit dann nicht auskennt, wirft man es halt schnell gleich wieder weg.

Bis auf den Dateinamen für die JSON-Datei sollte es so gehen:
Delphi-Quellcode:
program TestJSON1;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.IOUtils,
  REST.Json.Types,
  REST.Json;

type
  TBlock = class
  private
    FListe1: TArray<string>;
    FListe4: TArray<Integer>;
    FInt_1: Integer;
    FTxt_1: string;
    FBool_1: Boolean;
    FReal_1: Real;
  public
    property Liste1: TArray<string> read FListe1;
    property Liste4: TArray<Integer> read FListe4;
    property Int_1: Integer read FInt_1;
    property Txt_1: string read FTxt_1;
    property Bool_1: Boolean read FBool_1;
    property Real_1: Real read FReal_1;
  end;

  TContainer = class
  private
    { ja, wir könnten hier auch FBlöcke schreiben, aber das sind so Dinge, die bringe ich einfach nicht übers Herz. }
    [JSONName('Blöcke')] // needs REST.Json.Types
    FBloecke: TArray<TBlock>;
  public
    destructor Destroy; override;
    property Bloecke: TArray<TBlock> read FBloecke;
  end;

destructor TContainer.Destroy;
var
  item: TBlock;
begin
  for item in FBloecke do
    item.Free;

  inherited;
end;

procedure ParseJson();
var
  block: TBlock;
  FileContent: String;
  Container: TContainer;
begin
  FileContent := TFile.ReadAllText('<path\to\file.json>');
  Container := TJson.JsonToObject<TContainer>(FileContent);
  try
    for block in Container.Bloecke do
      Writeln(block.Txt_1);
  finally
    Container.Free;
  end;
end;

begin
  try
    ParseJson;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

Aviator 21. Dez 2021 17:40

AW: JSON einlesen - Hilfe für Anfänger
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1499505)
Das compiliert aber so nicht. Wenn man sich damit dann nicht auskennt, wirft man es halt schnell gleich wieder weg.

Naja ich bin mal davon ausgegangen, dass er die Klasse und die Prozedur selbst in eine Unit an die richtige Stelle schreiben kann. 😉

Was ich jetzt so beim Schreiben im Editor nicht mehr im Kopf hatte war, dass man wohl eine weitere Klasse mit einem Feld bauen muss in dass das Objekt dann konvertiert wird. 😅

Aber mit den vielen Beispielen hätte er das sicherlich hinbekommen können. 🙂


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:48 Uhr.
Seite 2 von 4     12 34      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz