Forum > Russian
Пытаюсь распарсить 2 JSONа и скопировать значениия
blackspaceghost:
Всем доброго времени суток, в общем пытаюсь распарсить 2 JSON объекта, в принципе всё получается, кроме одного но, во вложенном объекте тип jtArray напрочь отказывается копироваться в другой объект, ссылаясь на разного рода ошибки. (Хотя не во вложенном объекте всё работает, подходя таким же принципом) Поэтому и закрадывается вопрос, как быть-то, ведь оно должно работать, и должно работать так же. Я уже перепробовал разные подходы к решению данной задачи, ничего, все тщетно. Вложенный jtArray не поддаётся. Уповаю на вашу помощь и ниже прилагаю код и 2 JSON объекта:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- program Project1; {$mode objfpc}{$H+} uses {$IFDEF UNIX} cthreads, {$ENDIF} Classes, SysUtils, CustApp { you can add units after this }, jsonscanner, fpjson, jsonparser; type { TMyTimeTest } TMyTimeTest = class(TCustomApplication) private fFileData: string; fPath1: string; fPath2: string; fFlag: boolean; fStr1: string; fStr2: string; procedure SetPath1(path: string); procedure SetPath2(path: string); procedure SetFlag(flag: boolean); procedure SetStr1(str1: string); procedure SetStr2(str2: string); protected procedure DoRun; override; public JSONObject1, JSONObject2: TJSONObject; JSONEnum1, JSONEnum2: TBaseJSONEnumerator; constructor Create(TheOwner: TComponent); override; destructor Destroy; override; procedure WriteHelp; virtual; procedure WriteInfo; procedure SetFileData; procedure ParseAndSet; procedure WriteInFile; property Path1: string read fPath1 write SetPath1; property Flag: boolean read fFlag write SetFlag; property Str1: string read fStr1 write SetStr1; property Str2: string read fStr2 write SetStr2; end; { TMyTimeTest } procedure TMyTimeTest.SetPath1(path: string); begin fPath1 := path; end; procedure TMyTimeTest.SetPath2(path: string); begin fPath2 := path; end; procedure TMyTimeTest.SetFlag(flag: boolean); begin fFlag := flag; end; procedure TMyTimeTest.SetStr1(str1: string); begin fStr1 := str1; end; procedure TMyTimeTest.SetStr2(str2: string); begin fStr2 := str2; end; procedure TMyTimeTest.SetFileData; var L: TStringList; begin //if str1 = '' then // fPath1 := ParamStr(1) //else // fPath2 := ParamStr(2); fPath1 := '/media/sf_Devices/u1.json'; fPath2 := '/media/sf_Devices/u2.json'; try try L := TStringList.Create; L.LoadFromFile(fPath1); if L <> nil then begin fFileData := L.Text; Self.SetFlag(True); if str1 = '' then str1 := fFileData; end; finally L.Free; end; except ShowException(Exception.Create('1')); Terminate; Halt; end; //if str1 = '' then // fPath1 := ParamStr(1) //else // fPath2 := ParamStr(2); try try L := TStringList.Create; L.LoadFromFile(fPath2); if L <> nil then begin fFileData := L.Text; Self.SetFlag(True); if str2 = '' then str2 := fFileData; end; finally L.Free; end; except ShowException(Exception.Create('1')); Terminate; Halt; end; end; procedure TMyTimeTest.ParseAndSet; var JSONParser1, JSONParser2: TJSONParser; JNestObject1, JNestObject2: TJSONObject; JSONNestEnum1, JSONNestEnum2, JSONArrayEnum: TBaseJSONEnumerator; i: integer; begin JSONParser1 := TJSONParser.Create(str1, DefaultOptions); JSONParser2 := TJSONParser.Create(str2, DefaultOptions); try JSONObject1 := JSONParser1.Parse as TJSONObject; JSONObject2 := JSONParser2.Parse as TJSONObject; try JSONEnum1 := JSONObject1.GetEnumerator; JSONEnum2 := JSONObject2.GetEnumerator; try while JSONEnum1.MoveNext do while JSONEnum2.MoveNext do begin if JSONEnum1.Current.Value.JSONType = jtObject then begin JNestObject1 := JSONEnum1.Current.Value as TJSONObject; JNestObject2 := JSONObject2.Find(JSONEnum1.Current.Key) as TJSONObject; try JSONNestEnum1 := JNestObject1.GetEnumerator; JSONNestEnum2 := JNestObject2.GetEnumerator; while JSONNestEnum1.MoveNext do while JSONNestEnum2.MoveNext do begin if JSONObject2.FindPath(JSONEnum1.Current.key + '.' + JSONNestEnum1.Current.Key) <> nil then begin if JSONNestEnum1.Current.Value.JSONType = jtString then begin JNestObject2.Strings[JSONNestEnum1.Current.Key] := JSONNestEnum1.Current.Value.AsString; Break; end else if JSONNestEnum1.Current.Value.JSONType = jtNumber then begin JNestObject2.Integers[JSONNestEnum1.Current.Key] := JSONNestEnum1.Current.Value.AsInt64; Break; end else if JSONNestEnum1.Current.Value.JSONType = jtBoolean then begin JNestObject2.Booleans[JSONNestEnum1.Current.Key] := JSONNestEnum1.Current.Value.AsBoolean; Break; end else if JSONNestEnum1.Current.Value.JSONType = jtArray then begin JSONArrayEnum := TJSONArray(JSONNestEnum1.Current.Value).GetEnumerator; JSONObject2.Arrays[JSONNestEnum1.Current.Key].Clear; while JSONArrayEnum.MoveNext do JSONObject2.Arrays[JSONNestEnum1.Current.key].Add(JSONArrayEnum.Current.Value); //JSONObject2.Arrays[JSONNestEnum1.Current.Key] := (TJSONArray(JNestObject2.Items[2]));; //for i:=0 to TJSONArray(JNestObject2.Items[2]).Count-1 do end; Break; end; end; finally FreeAndNil(JSONNestEnum1); FreeAndNil(JSONNestEnum2); end; end else if JSONObject2.FindPath(JSONEnum1.Current.Key) <> nil then begin if JSONEnum1.Current.Value.JSONType = jtString then begin JSONObject2.Strings[JSONEnum1.Current.Key] := JSONEnum1.Current.Value.AsString; Break; end else if JSONEnum1.Current.Value.JSONType = jtNumber then begin JSONObject2.Integers[JSONEnum1.Current.Key] := JSONEnum1.Current.Value.AsInt64; Break; end else if JSONEnum1.Current.Value.JSONType = jtBoolean then begin JSONObject2.Booleans[JSONEnum1.Current.Key] := JSONEnum1.Current.Value.AsBoolean; Break; end else if JSONEnum1.Current.Value.JSONType = jtArray then begin JSONArrayEnum := TJSONArray(JSONEnum1.Current.Value).GetEnumerator; JSONObject2.Arrays[JSONEnum1.Current.Key].Clear; while JSONArrayEnum.MoveNext do JSONObject2.Arrays[JSONEnum1.Current.key].Add(JSONArrayEnum.Current.Value); Break; end; Break; end; Break; end; finally FreeAndNil(JsonEnum1); FreeAndNil(JsonEnum2); end; finally //FreeAndNil(JsonObject1); //FreeAndNil(JsonObject2); end; finally FreeAndNil(JsonParser1); FreeAndNil(JsonParser2); end; end; procedure TMyTimeTest.WriteInFile; var L: TStringList; begin L := TStringList.Create; try L.Text := Trim(JSONObject2.FormatJSON); L.SaveToFile(fPath2); ShowException(Exception.Create('0')); finally L.Free; JSONObject2.Free; end; end; procedure TMyTimeTest.DoRun; var ErrorMsg: string; begin // parse parameters if HasOption('h', 'help') then begin WriteHelp; Terminate; Exit; end; if HasOption('i', 'info') then begin WriteInfo; Terminate; Exit; end; // quick check parameters ErrorMsg := CheckOptions('h', 'help'); if ErrorMsg <> '' then begin ShowException(Exception.Create(ErrorMsg)); Terminate; Exit; end; { add your program here } Self.SetFileData; Self.SetFileData; if flag = True then begin Self.ParseAndSet; Self.WriteInFile; end; // stop program loop Terminate; end; constructor TMyTimeTest.Create(TheOwner: TComponent); begin inherited Create(TheOwner); StopOnException := True; end; destructor TMyTimeTest.Destroy; begin inherited Destroy; end; procedure TMyTimeTest.WriteHelp; begin { add your help code here } end; procedure TMyTimeTest.WriteInfo; begin end; var Application: TMyTimeTest; begin Application := TMyTimeTest.Create(nil); Application.Title := 'MyTimeTest'; Application.Run; Application.Free; end.
--- Code: Text [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- { "host":{ "wired": "192.168.209.2", "usb_wifi": "192.168.25.5", "ports":[2000, 23000, 40000] }, "port": { "wired": 20002, "usb_wifi": 20003 }, "devices": ["uspd", "rip", "asr"], "writedebug": True, "writecriticalsection": True }
--- Code: Text [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- { "host":{ "wired": "0.0.0.0", "usb_wifi": "0.0.0.0", "ports": [], "modem_managed_0": "0.0.0.0" }, "port": { "wired": 20002, "usb_wifi": 20002, "modem_managed_0": 20002 }, "devices": [], "writedebug": false, "writecriticalsection": false, "writemagicdebugid": -1, "writembusdebugid": -1 }
skalogryz:
--- Quote from: blackspaceghost on August 10, 2021, 08:46:40 am ---...пытаюсь распарсить 2 JSON объекта,... напрочь отказывается копироваться в другой объект
--- End quote ---
так парсить, или копировать? в чём задача состоит?
У TJsonData есть метод .Clone ты его пробовал ?
blackspaceghost:
Задача состоит в копировании значений совпадающих ключей в 2-х объектах, парсинг это как раз частный случай. Clone пробовал, не помогло тоже. Вообще, я написал на англоязычный форум, и там мне привели рабочий вариант: https://forum.lazarus.freepascal.org/index.php?topic=55763.msg414741#msg414741, только вот теперь не могу добавить из файла подгрузку, вылетают ошибки. Видимо, не могу привести в нормальный вид входные данные
zoltanleo:
А использование сторонних модулей не рассматривается? Например, этого
Red_prig:
Стандартный json парсер и его DOM по мне довольно ужасен, я сильно переписал парсер и DOM для своих нужд, если кому интересно:
https://github.com/red-prig/netlibs/tree/master/xpath
Navigation
[0] Message Index
[#] Next page