[erledigt] probleme beim parsen eines jsons

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

[erledigt] probleme beim parsen eines jsons

Beitrag von Dragon »

hallo liebe community,
Ich habe derzeit ein problem beim parsen eines json files, ich kriege es nicht richtig gepared er paarsed den hauptpunkt und den ersten beiden unterpunkte und fährt sich dann fest.(also die unterpunkte folgewort und anzahl)

hiermit versuche ich das json auszulesen

Code: Alles auswählen

begin
      writeln('fange an zu lesen');
      s := Copy(Content, 14, length(Content));
      Text := '';
      Text := LoadFile('./configs/' + s + '.json');
      J := GetJson(Text);
      //Lade Wortdatenbank
      i:= 0;
      i2:=0;
      quit:=false;
      repeat
        try
        writeln('lese haupt ein');
        setlength(database, i+1);
        database[i].wort1 := J.FindPath('Wortdatenbank['+ inttostr(i) +'].wort1').AsString;
        database[i].wort1 := J.FindPath('Wortdatenbank['+ inttostr(i) +'].wort2').AsString;
        writeln('ende haupteintrag');
        repeat
        try
        writeln('lese unter ein');
         setlength(database[i].folgewort, i2+1);
         setlength(database[i].anzahl, i2+1);
         writeln('trage ein');
         database[i].folgewort[i2] := J.FindPath('Wortdatenbank['+inttostr(i) +'].folgewort['+inttostr(i2)+']').AsString;
         writeln('anzahl');
         database[i].anzahl[i2] := J.FindPath('Wortdatenbank['+ inttostr(i) +'].anzahl['+ inttostr(i2)+']').Asinteger;
         inc(i2);
         if J.FindPath('Wortdatenbank['+inttostr(i) +'].folgewort['+inttostr(i2)+']').AsString = '' then break;
        except
        writeln('except ausgelöst unterpunkt');
        quit2:= true;
        end
        until quit2=true;
        writeln('zurück in haupt');
        i2:=0;
        inc(i);
        quit2 := false;
        except
         writeln('except ausgelöst hauptpunkt');
          quit:=true;
        end;
      until quit=true;
      text :='';
    end


das ist mein testjson file

Code: Alles auswählen

 
{
"Wortdatenbank": [{
"wort1":"das",
"wort2":"ist",
"folgewort": ["ein","auf","toll","der"],
"anzahl": ["3","1","1","1"]},
{
"wort1":"ist",
"wort2":"ein",
"folgewort": ["das"],
"anzahl": ["3"]},
{
"wort1":"ein",
"wort2":"das",
"folgewort": ["ist"],
"anzahl": ["3"]},
{
"wort1":"ist",
"wort2":"auf",
"folgewort": ["der"],
"anzahl": ["1"]},
{
"wort1":"auf",
"wort2":"der",
"folgewort": ["ist"],
"anzahl": ["1"]},
{
"wort1":"der",
"wort2":"ist",
"folgewort": ["doof"],
"anzahl": ["1"]},
{
"wort1":"ist",
"wort2":"doof",
"folgewort": ["das"],
"anzahl": ["1"]},
{
"wort1":"doof",
"wort2":"das",
"folgewort": ["ist"],
"anzahl": ["1"]},
{
"wort1":"ist",
"wort2":"toll",
"folgewort": ["das"],
"anzahl": ["1"]},
{
"wort1":"toll",
"wort2":"das",
"folgewort": ["ist"],
"anzahl": ["1"]}
]}


letztendlich soll alles in diesem record of array gespeichert werden

Code: Alles auswählen

Statistiken = packed record
    Wort1: string;
    Wort2: string;
    Folgewort: array of string;
    Anzahl: array of integer;
  //  Vorkommen: array of single;
  end;           
var
  database: array of Statistiken; 
Zuletzt geändert von Dragon am So 26. Jun 2016, 00:04, insgesamt 1-mal geändert.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: probleme beim parsen eines jsons

Beitrag von Michl »

Hab da mehrere Dinge gesehen. Z.B. fehlt in der ersten Schleife ein quit2 := False. Außerdem ist das Abfangen der Exception, falls keine Einträge mehr vorhanden sind, eher ungünstig, dafür gibt es TJSONData.Count.

Habe das mal mit deinen Daten probiert. So geht das bei mir:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  aFileStream: TFileStream;
  s: String;
  J, Data, FolgeWort, Anzahl: TJSONData;
  i, i2, i3: Integer;
  aStatistik: Statistiken;
begin
  aFileStream := TFileStream.Create('test.txt', fmOpenRead);
  SetLength(s, aFileStream.Size);
  aFileStream.Read(s[1], Length(s));
  aFileStream.Free;
 
  J := GetJSON(s);
  try
    SetLength(database, 0);
    Data := J.FindPath('Wortdatenbank');
    for i2 := 0 to Pred(Data.Count) do
    begin
      FolgeWort := Data.Items[i2].FindPath('folgewort');
      Anzahl    := Data.Items[i2].FindPath('anzahl');
      if FolgeWort.Count <> Anzahl.Count then
        Exception.Create('JSON corrupted');
      aStatistik.Wort1 := Data.Items[i2].FindPath('wort1').AsString;
      aStatistik.Wort2 := Data.Items[i2].FindPath('wort2').AsString;
      SetLength(aStatistik.Folgewort, FolgeWort.Count);
      SetLength(aStatistik.Anzahl,    Anzahl.Count);
      for i3 := 0 to Pred(FolgeWort.Count) do
      begin
        aStatistik.Folgewort[i3] := FolgeWort.Items[i3].AsString;
        aStatistik.Anzahl[i3]    := Anzahl.Items[i3].AsQWord;
      end;
      SetLength(database, Succ(Length(database)));
      database[High(database)] := aStatistik;
    end;
  finally
    J.Free;
  end;
end;

Sicher geht das auch noch anders zu lösen.

Viel Spaß!
Zuletzt geändert von Michl am So 26. Jun 2016, 00:20, insgesamt 2-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Dragon
Beiträge: 162
Registriert: Mi 31. Jul 2013, 15:07
OS, Lazarus, FPC: Ubuntu 16.04, CodeTyphon 5.80

Re: [erledigt] probleme beim parsen eines jsons

Beitrag von Dragon »

Vielen dank Michl funktioniert super :)

Gibs zufällig eine doku für den json parser, hab nur die beiden wiki artikel gefunden.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: [erledigt] probleme beim parsen eines jsons

Beitrag von Michl »

Habe da eben ein Rudiment (eine Schleife) einer alten Version im Code oben gesehen und entfernt.

Leider kenne ich weder eine Doku, noch die besagten Wiki-Artikel, hatte es eben nur intuitiv mit deinem Ansatz und deinen Daten probiert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Antworten