AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Json unbekanntes feld abfangen

Ein Thema von venice2 · begonnen am 15. Dez 2020 · letzter Beitrag vom 22. Dez 2020
Antwort Antwort
venice2
(Gast)

n/a Beiträge
 
#1

AW: Json unbekanntes feld abfangen

  Alt 15. Dez 2020, 21:37
Macht im fertigen Programm ca. 280 MB aus. Dafür ist man in 10 Minuten fertig.

Bis bald...
Thomas
Boahh.. 280 MB großartig
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
483 Beiträge
 
#2

AW: Json unbekanntes feld abfangen

  Alt 15. Dez 2020, 21:43
Boahh.. 280 MB großartig
Ok, ich hätte vielleicht genauer schreiben sollen: ...ca. 280 MB mehr mit der Unit SynCommons.pas.

Frohe Weihnachten...
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.553 Beiträge
 
Delphi 12 Athens
 
#3

AW: Json unbekanntes feld abfangen

  Alt 15. Dez 2020, 21:58
Ohne die meisten Debuginfos (Release) wird es kleiner.

Alternativ kannst du auch mit "externen Debuginfos" kompilieren.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (15. Dez 2020 um 22:02 Uhr)
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#4

AW: Json unbekanntes feld abfangen

  Alt 15. Dez 2020, 22:07
Ohne die meisten Debuginfos (Release) wird es kleiner.

Alternativ kannst du auch mit "externen Debuginfos" kompilieren.
Es war ein Witz
Er hat geschrieben 280 MB sollte wohl 280 KB sein.

Habe es mal versucht, es funktioniert auch nicht richtig oder ich mache was falsch.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  iRun, i, nRun: Integer;
  doc: TDocVariantData;
  docChannelGroup: PDocVariantData;
  docChannels: PDocVariantData;
begin
  doc.InitJSONFromFile('Channels_data.json', JSON_OPTIONS_FAST_EXTENDED);
  if not doc.B['success'] then
    Exit; //=>

  for iRun := 0 to doc.A['channel_groups'].Count - 1 do
  begin
    docChannelGroup := doc.A['channel_groups']._[iRun];
    for nRun := 0 to docChannelGroup.A['channels'].Count - 1 do
    begin
      docChannels := docChannelGroup.A['channels']._[nRun];
      for i := 0 to docChannels.A['channels'].Count - 1 do
      begin
        setLength(gChannels, i + 1);

        gChannels[i].display_alias := docChannels.S['display_alias'];
        gChannels[i].sharing := docChannels.B['sharing'];
        gChannels[i].is_radio := docChannels.B['is_radio'];
        gChannels[i].title := docChannels.S['title'];
        gChannels[i].cid := docChannels.S['cid'];
        gChannels[i].number := docChannels.I['number'];
        gChannels[i].recording := docChannels.B['recording'];
      end;
    end;
  end;
end;
erzählt mir irgendwas von
docChannels.A['channels'].Count wäre 0. ist es aber definitiv nicht.

Ich habe 172 Sender.

Habe die Channels_data.json mal angehängt.

EDIT:
Ok. Das problem ist wohl eher das ich nach dem Eintrag 'display_alias' suchen muss. Dieser hat 172 Einträge.
Wie komme ich daran?

Scheint nicht schlecht zu sein das Teil. @mytbo Danke.
Wenn auch etwas sehr mächtig.

Geändert von venice2 (17. Dez 2020 um 12:15 Uhr)
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#5

AW: Json unbekanntes feld abfangen

  Alt 16. Dez 2020, 04:26
zur zeit wird der Channel auf diese weise eingelesen.

Delphi-Quellcode:
  // Ignore: '{"channel_groups":'
  // a channel-definition begins with "display_alias": "
  PosNext := PosEx('"display_alias"', Data, 1); // get begin of first channel
  id := 0;
  n := 0;
//Log('UPDCHL', 'LEN: ' + inttostr(length(data)));
  while (PosNext > 0) do
  begin
//LOG('UPDCHL', '------------------------');
    inc(PosNext, 1);
    inc(n);
    Application.ProcessMessages;
    // --- Read all values in order of apperance:
    // "display_alias" - NOZ USED // 1)
    sha := GetBool(posnext, Data, '"sharing": '); // 2)
    rad := GetBool(posnext, Data, '"is_radio": '); // 3)
    tit := GetStr(PosNext, Data, '"title": "', '"'); // 4)
    tit := DecodeJString(tit);
    cid := GetStr(posnext, Data, '"cid": "', '"'); // 5)
//Log('UPDCHL', inttostr(PosNext) + ' | CID: ' + cid);
    num := GetStr(PosNext, Data, '"number": ',','); // 6)
//Log('UPDCHL', inttostr(PosNext) + ' | ZatNum: ' + num + ' | RecNum: ' + inttostr(n));
    // Here: ... EPG-NEXT 7)
    rec := GetBool(posnext, Data, '"recording": '); // 8)
    // --- Check if Channel already exists:
    x := GetChlbyCID(1, cid, ChlRec);
    if (x < 0) then
    begin
      // NOT FOUND !!! New ChlRec
      New(ChlRec); // create a new record:
      id := FCHLList.Add(ChlRec);
//Log('UPDCHL', 'New ChlRec: '); // + inttostr(id +1) + ' - ' +booltostr(rad, true));
      CHLrec.SortNum := -1;
      CHLrec.QSelect := -1; // no Quality-Rec selected
      // ----- DYNAMIC-DATA -----
      ChlRec.Qualy := TList.Create;
      CHLrec.EPG := TList.Create;
    end;
// else
// Log('UPDCHL', '********** CHL AVAILABLE: ' + booltostr(ChlRec.Is_Radio, true));
    // --- Set values new:
    ChlRec.Sharing := sha;
    ChlRec.Is_Radio := rad;
    StrLCopy(CHLrec.Title, PAnsiChar(tit), High(ChLrec.Title) - 1);
    StrLCopy(CHLrec.CID, PAnsiChar(cid), High(CHLrec.CID) - 1);
    ChlRec.Num := StrToInt(num);
    ChlRec.Recording := rec;
    // --- check CHANNEL-QUALITIES:
    // Section "qualities" will / must be present
    // we should have min. 1 (SD) , mostly 2 (HD+SD), more ?
    // TRICKY: first read "recommendations" for max. loop-position !
    posrem:= PosEx('"recommendations"', Data, posnext); // REMAIN "JUMP"
    numQRec := -1;
    // --- Clear QRecs if available:
    for i := 1 to ChlRec.Qualy.Count do
      Dispose(PChlQualyRec(ChlRec.Qualy[i - 1]));
    ChlRec.Qualy.Clear;
    // --- Read QRecs new
    s := GetStr(posnext, Data, '"stream_types": [', '],'); // get first qualy-data
    while (PosNext > 0) AND (PosRem > PosNext) do
    begin
      inc(numQrec);
      New(QRec); // 10)
      ChlRec.Qualy.Add(QRec);
      FillChar(QRec^, sizeof(TChlQualyRec), 0);
      // title - UNUSED HERE
      QRec.stream_types := GetSTreamTypes(s);
      QRec.level := 0; // default undefined
      s := GetStr(posnext, Data, '"level": "', '",');
      if (s = 'hd') then QRec.level := 2;
      if (s = 'sd') then QRec.level := 1;
      s := GetStr(posnext, Data, '"logo_token": "', '",');
      StrLCopy(QRec.logo_token , PAnsiChar(s), High(QRec.logo_token) - 1);
      s := GetStr(posnext, Data, '"availability": "', '"');
      QRec.available := (s = 'available');
      inc(PosNext, 5); // jump over last bracketsm komma & spaces !
//LOG('UPDCHL', '--- Q' + inttostr(numQRec) + ' - avail: ' + booltostr(QRec.available, true) +
// ' | level: ' + inttostr(QRec.level));
      // ----- Check if selectable:
      if (ChlRec.QSelect < 0) then
        if QRec.available then ChlRec.QSelect := ChlRec.Qualy.Count - 1;
      s := GetStr(posnext, Data, '"stream_types": [', '],'); // get next qualy-data
    end;
//LOG('UPDCHL', '--- selected: ' + inttostr(ChlRec.QSelect));
    PosNext := PosRem; // !!! ... because PosNext is in range of next channel !
    // Ignore: "recommendations" // 11)
    // Here: ... EPG-Now 7)
    // Ignore: "id": "ard", // 13)
    // Ignore: "aliases": ["daserste"] // 14)
    // IGNORE: FAV-block
    PosNext := PosEx('"display_alias"', Data, PosNext); // // get begin of next channel
  end;
Wie man sehen kann ist das sehr aufwendig und es ist nicht immer garantiert das diese art des Parsen zum gewünschten erfolg führt.
Meine frage daher wie kann ich das mit mORMot Json Parser umsetzen?
Sollte das funktionieren sollen mir die 280 KB egal sein.

Kenne das Framework nicht und ellenlange Englische Seiten zu lesen ist nicht mein Ding.

EDIT:
Dann kann ich
ShowMessage(docPrograms.S['g'].ToCSV);
In D2010 nicht übergeben so wie man im Shot sehen kann. (Ist nur ein String nicht gesplittet)
Zitat:
[DCC Error] Unit1.pas(125): E2018 Record, object or class type required

Geändert von venice2 (16. Dez 2020 um 16:27 Uhr)
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
483 Beiträge
 
#6

AW: Json unbekanntes feld abfangen

  Alt 16. Dez 2020, 10:28
Ich habe das jetzt nur mal schnell überflogen. So sollte es aber funktionieren. Wenn du heute Abend (Nacht) noch ein Problem damit hast, sage einfach bescheid. Ich schaue mir das dann gerne mal an.
Delphi-Quellcode:
var
  iRun, nRun: Integer;
  doc: TDocVariantData;
  docChannelGroup: PDocVariantData;
  docChannels: PDocVariantData;
begin
  doc.InitJSONFromFile('Channels_data.json', JSON_OPTIONS_FAST_EXTENDED);
  if not doc.B['success'] then Exit; //=>

  for iRun := 0 to doc.A['channel_groups'].Count - 1 do
  begin
    docChannelGroup := doc.A['channel_groups']._[iRun];
    for nRun := 0 to docChannelGroup.A['channels'].Count - 1 do
    begin
      docChannels := docChannelGroup.A['channels']._[nRun];
      ShowMessage(docChannels.S['display_alias']);
      ShowMessage(docChannels.I['number'].ToString);
    end;
  end;
Bis bald...
Thomas
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#7

AW: Json unbekanntes feld abfangen

  Alt 16. Dez 2020, 10:34
Zitat:
Wenn du heute Abend (Nacht) noch ein Problem damit hast, sage einfach bescheid. Ich schaue mir das dann gerne mal an.
Das ist nett von dir werde es mal implementieren.
Danke schön.

Hmm.. Ich glaube wir haben uns nicht richtig verstanden.
Dein Schnipsel gibt mir die Value von display_alias zurück.
Das ist aber nicht was ich wollte.

Mein bestreben ist in der Json nach 'display_alias' zu suchen und darauf hin den Count auszulegen.
display_alias kommt 172 mal in der Json vor diese und die nachfolgenden Einträge muss ich parsen bis zum nächsten 'display_alias'
und so lange bis er halt nicht mehr vorkommt.

Also nicht auf docChannels sondern auf
docChannels.S['display_alias']

Es gibt ja nur diese möglichkeiten..
docChannels.SearchItemByProp
docChannels.SearchItemByValue

aber beides führte nicht zum gewünschten Ergebnis.

PS:
EPG ist fertig und funktioniert soweit.
Nun muss ich nur noch die Channels erfolgreich rüberbringen.

so geht es nicht..
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
type
  TChannelsData = record
    display_alias: string;
    sharing: BOOL;
    is_radio: BOOL;
    title: string;
    cid: string;
    number: LongInt;
    recording: BOOL;
    success: BOOL;
  end;
var
  iRun, i, nRun: Integer;
  doc: TDocVariantData;
  docChannelGroup: PDocVariantData;
  docChannels: PDocVariantData;
  x: TRawUtf8DynArray;
  gChannels: array of TChannelsData;
begin
  doc.InitJSONFromFile('Channels_data.json', JSON_OPTIONS_FAST_EXTENDED);
  if not doc.B['success'] then
    Exit; //=>

  for iRun := 0 to doc.A['channel_groups'].Count - 1 do
  begin
    docChannelGroup := doc.A['channel_groups']._[iRun];
    for nRun := 0 to docChannelGroup.A['channels'].Count - 1 do
    begin
      docChannels := docChannelGroup.A['channels']._[nRun];
      for i := 0 to docChannels.A['display_alias'].Count - 1 do // Wie komme ich an den Count und wie finde ich den nächsten Eintrag von 'display_alias'
      begin
        setLength(gChannels, i + 1);

        gChannels[i].display_alias := docChannels.S['display_alias'];
        gChannels[i].sharing := docChannels.B['sharing'];
        gChannels[i].is_radio := docChannels.B['is_radio'];
        gChannels[i].title := docChannels.S['title'];
        gChannels[i].cid := docChannels.S['cid'];
        gChannels[i].number := docChannels.I['number'];
        gChannels[i].recording := docChannels.B['recording'];
      end;
    end;
  end;
end;

Geändert von venice2 (16. Dez 2020 um 10:58 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 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-2025 by Thomas Breitkreuz