![]() |
AW: JSON einlesen - Hilfe für Anfänger
@Aviator
Nein das habe ich nicht überlesen, sondern gut eine 1/2 Stunde drüber gegrübelt, wie das funktiert. Ohne Ergebnis. Dein JSON ist auch leicht anders als meiner - siehe auch mein Anhang in #9 mit dem reellen JSON. Ich denke der Unterschied und die Art das zu parsen ist hier sehr wichtig ?! Problem bzw. wichtig ist: - ich will alle Einträge (Bloack_A -> _Z) durchlaufen und deren Namen lesen - Nicht alle (Array- ?) Eintäge sind dabei wichtig und können übersprungen werden - Auch sind nicht alle Werte (Pairs, Arrays ?!) datunter notwendig - Teilweise brauche ich jeweils auch unterschiedliche "Sätze" (z.B. A] Liste_1 und Int_1, B] Liste_2 und Int_2) Ich müsste das also sozusagen schon zeilenweise in Loop's "durchkauen". @Uwe .... hat er aber eben nicht. :? |
AW: JSON einlesen - Hilfe für Anfänger
Ich versuche noch mal, das reelle JSON in Post #9 zu beschreiben und wie ich es bisher "zu Fuß" in vorherigen Datenversion gelesen habe:
Das 'äußere' Objekt namens "channels" interessiert mich nicht. Eine äußere Schleife liest dann alle TV-Sendernamen durch (bis ca. 150) Die brauche ich nicht alle, nur bestimmte. Unterhalb der jeweiligen Sendernamen liegen dann sozusagen Listen aus Records mit Daten, welche die jeweilige Sendung beschreiben. (Name, Start-/Sop-Zeit, ID's mit Verweisen auf Logos und EPG-Detail-Daten, etc.) Auch die brauche ich nicht immer alle. In dem Beispiel mit TBlocks müsste ich dann z.B. wissen, wie der Block heisst. Da Zatto nicht maximale Anzahl von Daten (Sendungen für mehrere Tage) hergibt, muss man "brückchenweise" (am besten in 6-Atunden Abschnitten) wiederholte die Daten ziehen. Daraus puzzle ich mir dann meinen EPG für ca. 2 Wochen zusammen und / oder mache Updates bei Änderungen. So viel zum Sinn und Zweck der Veranstaltung. |
AW: JSON einlesen - Hilfe für Anfänger
Irgendwie verstehe ich was Du meinst, ich verstehe jedoch nicht, wo konkret das Problem liegt.
Da ich nur ein olles Delphi 7 habe, nix JSon und passende Klassen schon mitgeliefert, hab' ich mir mal für ein konkretes "JSon-Problem" folgende Hilfroutine geschrieben:
Delphi-Quellcode:
Stringliste rein, Stringliste raus.
procedure MyJSonSplit(sl : TStringList);
var input : TMemoryStream; output : TMemoryStream; ch : Char; ch2 : Char; cr : Char; lf : Char; i : Integer; begin input := TMemoryStream.Create; output := TMemoryStream.Create; for i := 0 to sl.Count - 1 do sl[i] := AnsiReplaceText(sl[i],'"','"'); sl.SaveToStream(input); input.Position := 0; if input.Size > 0 then begin cr := #13; lf := #10; if input.Read(ch,1) > 0 then begin repeat case ch of '{','[',']','}' : begin output.Write(cr,1); output.Write(lf,1); output.Write(ch,1); output.Write(cr,1); output.Write(lf,1); end; ',' : begin input.Read(ch2,1); case ch2 of '"' : begin output.Write(cr,1); // eventuell ersten 3 Zeilen weglassen? output.Write(lf,1); output.Write(ch,1); output.Write(cr,1); output.Write(lf,1); output.Write(ch2,1); end; else output.Write(ch,1); input.Position := input.Position - 1; end; end; else output.Write(ch,1); end; if input.Position mod 1000 = 0 then Application.ProcessMessages; until input.Read(ch,1) = 0; end; output.Position := 0; sl.LoadFromStream(output); end; output.Free; input.Free; end; Damit sind alle Daten zeilenweise aufgebröselt. Wenn man nun diese Struktur kennt, kann man das auch entsprechend in 'ner For-Schleife auswerten, Bereiche überlesen, ... Eventuell wäre das ja ein Ansatz für Dich. Und nein: Eine professionelle Lösung ist das nicht, für's Hobbyprogrammieren aber ausreichend ;-) |
AW: JSON einlesen - Hilfe für Anfänger
Der Ansatz, JSON 'per Hand' zu zerlegen, scheint mir nicht sinnvoll oder viel zu mühevoll.
Ich habe hier ein Beispiel für Postgres SQL gemacht. ![]() Dort werden ein paar Beispieldaten in eine Tabelle eingefügt und zerlegt. Es sind anfangs ein paar Statements aufgeführt, die die grobe Zerlegung zeigen, am Ende dann ein paar "Anwendungsfälle". Dort im Browser ist es etwas lahm, auf einer normalen DB geht es zumindest mit den Beispieldaten aber flott. |
AW: JSON einlesen - Hilfe für Anfänger
Liste der Anhänge anzeigen (Anzahl: 1)
Ausgehend von Uwes Konsolenprogramm und den richtigen Daten aus #9 aus dem Archiv schnell was zusammengezimmert.
Ganzes Projekt mit Beispieldaten im Anhang als ZIP-Archiv. Mir ist bewusst, dass in diesem Ansatz die Sendernamen fehlen, da es sich hier um eine 1:1-Umsetzung der Json-Daten handelt. Die Transformation in das gewünschte Datenformat steht noch aus, da uns dies unbekannt ist TERWI. Kann aber ggf. durch RTTI geholt werden ( ![]() Dies überbleibt dem geneigten Leser als Fingerübung und Hausaufgabe.
Delphi-Quellcode:
program JsonZattoo;
{$APPTYPE CONSOLE} uses System.SysUtils, System.IOUtils, REST.Json, ZattooTypes in 'ZattooTypes.pas'; procedure ParseJson(); var Root: TRoot; LChannels: TChannels; LChannelInfo: TChannelInfo; LEPGInfo: TEPGInfo; FileContent: string; Txt: string; begin FileContent := TFile.ReadAllText('EPG_GUIDE.json'); Root := TJson.JsonToObject<TRoot>(FileContent); try LChannels := Root.ChannelContainer.Channels; for LChannelInfo in LChannels do begin for LEPGInfo in LChannelInfo do begin Writeln('ID: ', LEPGInfo.id); Writeln('Title: ', LEPGInfo.title); if not LEPGInfo.episode_title.IsEmpty then begin Writeln('Episode: ', LEPGInfo.episode_title); end; if Length(LEPGInfo.genre) > 0 then begin Writeln(' Genre(s):'); for Txt in LEPGInfo.genre do begin Writeln(' ' + Txt); end; end; Writeln('--------------------'); end; end; finally Root.Free; end; end; begin ReportMemoryLeaksOnShutdown := True; try ParseJson; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln end.
Delphi-Quellcode:
Beispielausgabe:
unit ZattooTypes;
interface uses REST.Json.Types; 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 write Fid; property title: string read FTitle write FTitle; property episode_title: string read FEpisode_title write FEpisode_title; property genre: TArray<string> read FGenre write FGenre; end; TChannelInfo = TArray<TEPGInfo>; TChannels = TArray<TChannelInfo>; TChannelContainer = class private Fsixx_deutschland: TChannelInfo; Fard: TChannelInfo; Fdeutschesmusikfernsehen: TChannelInfo; F3sat: TChannelInfo; function GetChannels: TChannels; public destructor Destroy; override; property Channels: TChannels read GetChannels; { // optional, wenn du nur eine Handvoll Sender brauchst und den direkten Zugriff willst, ansonsten per Channels-Property property deutschesmusikfernsehen: TChannelInfo read Fdeutschesmusikfernsehen write Fdeutschesmusikfernsehen; property ard: TChannelInfo read Fard write Fard; property _3sat: TChannelInfo read F3sat write F3sat; property sixx_deutschland: TChannelInfo read Fsixx_deutschland write Fsixx_deutschland; } end; TRoot = class private [JSONName('channels')] FChannels: TChannelContainer; public destructor Destroy; override; property ChannelContainer: TChannelContainer read FChannels; end; implementation destructor TRoot.Destroy; begin FChannels.Free; inherited; end; destructor TChannelContainer.Destroy; var ChannelInfo: TChannelInfo; EPGInfo: TEPGInfo; begin for ChannelInfo in Self.Channels do begin for EPGInfo in ChannelInfo do begin EPGInfo.Free; end; end; inherited; end; function TChannelContainer.GetChannels: TChannels; begin Result := [Fsixx_deutschland, Fard, Fdeutschesmusikfernsehen, F3sat]; end; end.
Code:
ID: 238874757
Title: Charmed - Zauberhafte Hexen Episode: Vergissmeinnicht Genre(s): Drama Fantasy Mystery -------------------- ID: 239947163 Title: Charmed - Zauberhafte Hexen Episode: Die Ohnmacht der Drei Genre(s): Drama Fantasy Mystery -------------------- ID: 238874759 Title: Charmed - Zauberhafte Hexen Episode: Tödliche Liebe Genre(s): Drama Fantasy Mystery -------------------- ID: 238874760 Title: Charmed - Zauberhafte Hexen Episode: Opfer der Sehnsucht Genre(s): Drama Fantasy Mystery -------------------- ID: 238906082 Title: ZDF-Mittagsmagazin Genre(s): News Magazine Society -------------------- ID: 238906083 Title: Tagesschau Episode: vom 21.12.2021, 14:00 Uhr Genre(s): News Politics Weather -------------------- ID: 238906084 Title: Rote Rosen Episode: Folge 3475 Genre(s): Drama Soap -------------------- ID: 238906085 Title: Tagesschau Episode: vom 21.12.2021, 15:00 Uhr Genre(s): News Politics Weather -------------------- ID: 238906086 Title: Sturm der Liebe Episode: Folge 3742 Genre(s): Romance & Love Soap -------------------- ID: 238906087 Title: Tagesschau Episode: vom 21.12.2021, 16:00 Uhr Genre(s): News Politics Weather -------------------- ID: 238906088 Title: Verrückt nach Meer Episode: Abenteuer am Öresund Genre(s): Travel -------------------- ID: 240036356 Title: Das große Wunschkonzert Episode: Kastelruther Spatzen Genre(s): Music -------------------- ID: 240036357 Title: Musiktipps Genre(s): Music -------------------- ID: 240036358 Title: Teleshopping Genre(s): Talk Show Home Shopping -------------------- ID: 240036359 Title: Bianca: Ihre schönsten Lieder Genre(s): Music -------------------- ID: 240036360 Title: Musiktipps Genre(s): Music -------------------- ID: 240036361 Title: Teleshopping Genre(s): Talk Show Home Shopping -------------------- ID: 238905942 Title: Von Sibirien nach Japan Episode: Wildes Kamtschatka -------------------- ID: 238905944 Title: Von Sibirien nach Japan Episode: Im Banne der Inseln Genre(s): Nature -------------------- ID: 238879507 Title: Spitzbergen - Leben in Europas Kühlschrank Genre(s): Nature -------------------- ID: 238879508 Title: Zimtstern und Halbmond Genre(s): Romance & Love Travel -------------------- |
AW: JSON einlesen - Hilfe für Anfänger
Wow, so viel Code ! Danke euch allen. Aber wie immer das ABER:
@Delphi.Narium So was in der Art hab ich hier schon für die Vorgänger-Datenversion. Das wollte ich eigentlich etwas einfacher und übersichtlicher haben. @jobo Hm, auch noch SQL/Datenbank mit ins Boot ist eigentlich weit am Ziel vorbei... Und ja: JSON (einfach) per Hand zu zerlegen ist die Intention. Siehe weiter unten. @TiGü Yepp, das funzt ! Allerdings müsste ich da sicher erst mal einen extended Durchblickerkurs machen, um zu verstehen wie das funktioniert und wie man das dann ggf. noch erweitert/anpasst. Sehe ich das richtig, das die auserwählten Sender statisch im TChannelContainer vorgegeben sind ? Falls ja: Das sollte vom User änderbar sein (hier mit Senderlisten-Editor) Ich hab gesten Nacht noch rumgebastelt und dabei ist folgendes herausgekommen
Delphi-Quellcode:
Das ist mit Bordmitteln kurz, einfach, simpel und funzt so wie ich mir das denke.
// https://www.generacodice.com/en/articolo/4308375/how-to-parse-nested-json-object-in-delphi-xe2
procedure TForm1.ParseJson(data : string); var JsonObj : TJSONObject; JsonArray : TJSONArray; JsonValue : TJSonValue; chl : TJSonValue; JsonPair : TJSONPair; i, ii, n : integer; LItem : TJSONValue; begin JsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(data),0) as TJSONObject; try JsonValue := JsonObj.Get('channels').JsonValue; for i := 0 to TJSONArray(JsonValue).Size - 1 do begin chl := TJSONArray(JsonValue).Get(i); JsonPair := TJSONPair(chl); // Listet den Sender-Namen Memo.Lines.Add(Format('Channel: %s',[JsonPair.JsonString.Value])); n := 1; for LItem in TJSONArray(JsonPair.JsonValue) do begin // Listet entsprechend Anzahl der Programme je Sender // .... den 'Inhalt' zwischen [ und ] Memo.Lines.Add('- Programm: ' + inttostr(n)); inc(n); // ... wie bekomme ich hier Zugriff auf die ProgrammDaten ? // also den 'Inhalt' zwischen { und } end; end; finally JsonObj.Free; end; end; ... fehlt nur noch die "Kleinigkeit" siehe Text. Da fehlt mir noch das Verständnis bei JSON. Vielleicht kann da jemand aushelfen und den letzen Denkanstoß geben ?! |
AW: JSON einlesen - Hilfe für Anfänger
HA - ich habs raus !
Delphi-Quellcode:
Das war zwar mit Vollgas Versuch und Irrtum, aber lüppt.
// https://www.generacodice.com/en/articolo/4308375/how-to-parse-nested-json-object-in-delphi-xe2
procedure TForm1.ParseJson(data : string); var JsonObj : TJSONObject; JsonValue : TJSonValue; chl : TJSonValue; dat : TJSonValue; JsonPair : TJSONPair; DataPair : TJSONPair; i, ii, n : integer; LItem : TJSONValue; begin Memo.Lines.BeginUpdate; JsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(data),0) as TJSONObject; try JsonValue := JsonObj.Get('channels').JsonValue; for i :=0 to TJSONArray(JsonValue).Size - 1 do begin chl := TJSONArray(JsonValue).Get(i); JsonPair := TJSONPair(chl); Memo.Lines.Add(Format('Channel: %s',[JsonPair.JsonString.Value])); n := 1; for LItem in TJSONArray(JsonPair.JsonValue) do begin Memo.Lines.Add('-- Programm: ' + inttostr(n)); inc(n); for ii := 0 to TJSONArray(LItem).Size - 1 do begin dat := TJSONArray(LItem).Get(ii); DataPair := TJSONPair(dat); Memo.Lines.Add(Format(' ---- %s : %s',[DataPair.JsonString.Value, DataPair.JsonValue.Value])); end; end; end; finally JsonObj.Free; end; Memo.Lines.EndUpdate; end; |
AW: JSON einlesen - Hilfe für Anfänger
Zitat:
Und es ist wirklich einfach. Wenn man keine Umbenennung haben will, reichen ca 3 Zeilen SQL. Zugegeben, auf einer Apple Watch läuft es nicht. Mir war eigentlich auch wichtig zu zeigen, dass man da nicht Buchstabe für Buchstabe dran geht. (Auch ohne DB) Aber man kann es bestimmt auch in SQLite machen, das hat auch ganz gute JSON Funktionen und kleineren Fußabdruck. |
AW: JSON einlesen - Hilfe für Anfänger
Zitat:
|
AW: JSON einlesen - Hilfe für Anfänger
Zitat:
Delphi-Quellcode:
procedure ParseJsonTERWI;
var JsonRoot, JsonChannels, JsonEPGInfo: TJSONObject; JsonEPGInfos, JsonEPGDetailInfoArray: TJSONArray; JsonValue, JsonValue2, JsonSingleChannel: TJSonValue; JsonPair, JsonPair2: TJSONPair; I, N, J: integer; FileContent, ProgramName: string; begin FileContent := TFile.ReadAllText('EPG_GUIDE.json'); JsonRoot := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(FileContent), 0) as TJSONObject; try JsonValue := JsonRoot.Get('channels').JsonValue; if JsonValue is TJSONObject then begin JsonChannels := TJSONObject(JsonValue); Writeln('Es gibt soviele Kanäle: ', JsonChannels.Count); Writeln('Enter-Taste drücken...'); Readln; Writeln(sLineBreak + 'Auflistung der Kanäle...'); N := 1; for JsonPair in JsonChannels do begin ProgramName := JsonPair.JsonString.Value; Writeln(N.ToString + '. ', ProgramName); Inc(N); end; Writeln(sLineBreak + 'EPG-Informationen der ersten 3 Sender...'); Writeln('Enter-Taste drücken...'); Readln; N := 1; for JsonPair in JsonChannels do begin if JsonPair.JsonValue is TJSONArray then begin JsonEPGInfos := TJSONArray(JsonPair.JsonValue); Writeln(sLineBreak + N.ToString + '. ', ProgramName + ' hat soviele EPG-Informationen: ', JsonEPGInfos.Count); for I := 0 to JsonEPGInfos.Count - 1 do begin JsonValue2 := JsonEPGInfos.Items[I]; if JsonValue2 is TJSONObject then begin JsonEPGInfo := TJsonObject(JsonValue2); Writeln('...die EPG-Information hat soviele Einträge: ', JsonEPGInfo.Count); for JsonPair2 in JsonEPGInfo do begin // das hier wäre die Stelle wo du aus JsonPair2.JsonValue dir die nötigen Informationen // für deine Klassenstruktur/Liste/EPG-Guide zusammenpuzzeln musst. Writeln('......', JsonPair2.JsonString.Value, ': ', JsonPair2.JsonValue.ToString); // Wenn JsonPair2.JsonValue ein Array ist (z.B. Genres), dann hier nochmal genauer reingucken: if JsonPair2.JsonValue is TJSONArray then begin JsonEPGDetailInfoArray := TJSONArray(JsonPair2.JsonValue); for J := 0 to JsonEPGDetailInfoArray.Count - 1 do begin Writeln('.........', JsonEPGDetailInfoArray.Items[J].Value); end; end; end; end; end; end; Inc(N); if N = 3 then begin Writeln(sLineBreak + 'Damit es nicht zuviel wird, brechen wir hier nach 3 Sendern ab!'); Break; end; end; // Beispiel für einzelnen Sender -> hier dann wie oben auswerten! JsonSingleChannel := JsonChannels.GetValue('ard'); if JsonSingleChannel is TJSONArray then begin JsonEPGInfos := TJSONArray(JsonSingleChannel); // usw. usf. end; end; Writeln('Enter-Taste drücken...'); Readln; finally JsonRoot.Free; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz