You are not logged in.
Hello,
I am using your very good syncrossplatformJson unit to process Json data.
But I have not found a mode to extract a field using a dot path.
For example, with this Json:
{"obj":{"primo":12,"secondo":"abcd",
"terzo":{"val":"A123","valnum":"85","valfloat":"98.6"}
}
}
how I can obtain 98.6 passing path 'obj.terzo.valfloat'?
Something as:
Var
v: variant;
jsonOb: variant;
begin
// create the Json variant
...
v:=JsonFromPath(jsonOb, 'obj.terzo.valfloat');
end;
Offline
Try with _Safe(JsonOb).GetValueByPath(...
Offline
Thank you, but in SynCrossPlatformJSON.pas there is no function GetValueByPath,
nor _Safe class.
Note that I am using the unit stand alone, not with the entire Mormot framework.
Offline
Sorry, I've missed part of you using CrossPlatform unit, there's likely nothing ready for it. Try to copy GetValueByPath from SynCommons or mormot.core.variants
Offline
Hello, at end I wrote a simple recursive method, JSONFromPath, added to TJsonVariantData record.
Maybe it could be added to unit.
Regards
// ------------ Code ---------------------------------------------------------------------
TJSONVariantData = record
......
public
......
// Recursively search and extract a Json element, object, array or simple types
// having as input a path, ex. "fielda.fieldb.fieldc"
function JSONFromPath(const path: string): Variant;
......
implementation
.....
function TJSONVariantData.JSONFromPath(const path: string): Variant;
var
i: Integer;
res, resJson: Variant;
begin
Result:=Variants.Null;
if (Variant(Self)= variants.Unassigned) or (Variant(Self)=Variants.Null) then
begin
Exit;
end;
i := Pos('.',Path);
if i=0 then
begin
res:= Self.Value[path] ;
if (res = Variants.Unassigned) then
begin
Exit;
end;
if VarIsStr(res) or VarIsType(res, vtAnsiString) or VarIsType(res, vtWideString) then
Result:=VarToStr(res)
else
begin
resJson:=JSONVariant(res);
if (TJSONVariantData(resJson).Kind in [jvObject, jvArray]) then
Result := resJson
else
Result:=res;
end;
end else begin
Result := TJSONVariantData(JSONVariant(Self.Value[Copy(path,1,i-1)])).JSONFromPath(Copy(path, i+1) );
end;
end;
// -------------------- Tests
var
doc, newItem, newItem2: Variant;
doc.obj:=JSONVariant('{}');
doc.obj.primo:=12;
doc.obj.secondo:='abcd';
newItem:=JSONVariant('{"val": "A123", "valnum": "85", "valfloat": "98.6"}');
doc.obj.terzo:=newItem;
newItem2:=TJSONVariantData(doc).JSONFromPath('obj.terzo');
js:=newItem2;
writeln('obj.terzo: ',js);
newItem2:=TJSONVariantData(doc).JSONFromPath('obj.terzo.val');
js:=newItem2;
writeln('obj.terzo.val: ',js);
newItem2:=TJSONVariantData(doc).JSONFromPath('obj.terzo.valnum');
js:=newItem2;
Writeln('obj.terzo.valnum: ',js);
newItem2:=TJSONVariantData(doc).JSONFromPath('obj.terzo.valfloat');
js:=newItem2;
Writeln('obj.terzo.valfloat: ',js);
// not existing
newItem2:=TJSONVariantData(doc).JSONFromPath('obj.terzo.none');
js:=BoolToStr(VarIsNull( newItem2), True);
Writeln('Not existing: ',js);
Offline