#1 Re: Other components » Field extraction with path in unit syncrossplatformJson » 2024-03-21 12:23:21

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);

#2 Re: Other components » Field extraction with path in unit syncrossplatformJson » 2024-03-20 19:09:29

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.

#3 Other components » Field extraction with path in unit syncrossplatformJson » 2024-03-20 18:18:15

gidesa
Replies: 4

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;

Board footer

Powered by FluxBB