You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用TJsonDataObjects按路径删除JSON记录及获取节点路径问询

TJsonDataObjects 路径操作问题解决方案

1. 按路径删除JSON节点的实现

你当前的截断路径找父节点的思路是无需修改组件源码的最优实现,只需要把逻辑封装成通用函数即可达到和原生DeletePath方法一致的使用体验:

  • 拆分目标路径为父路径和末端键/索引,例如路径Level1.Level2.Level3拆分后父路径为Level1.Level2,末端键为Level3
  • 通过路径获取父节点实例,判断父节点是对象类型还是数组类型
  • 对应调用对象的Delete(键名)方法或数组的Delete(索引)方法完成删除
    封装示例代码如下:
procedure DeleteJsonPath(Json: TJsonDataObject; const Path: string);
var
  LastDotPos: Integer;
  ParentPath, ChildKey: string;
  ParentNode: TJsonValue;
  ParentObj: TJsonObject;
  ParentArr: TJsonArray;
  ChildIdx: Integer;
begin
  LastDotPos := LastDelimiter('.', Path);
  // 根节点不支持删除,直接退出
  if LastDotPos = 0 then Exit;
  ParentPath := Copy(Path, 1, LastDotPos - 1);
  ChildKey := Copy(Path, LastDotPos + 1, MaxInt);
  ParentNode := Json.Path[ParentPath];
  if not Assigned(ParentNode) then Exit;

  if ParentNode is TJsonObject then
  begin
    ParentObj := TJsonObject(ParentNode);
    if ParentObj.Contains(ChildKey) then
      ParentObj.Delete(ChildKey);
  end
  else if ParentNode is TJsonArray then
  begin
    ParentArr := TJsonArray(ParentNode);
    if TryStrToInt(ChildKey, ChildIdx) and (ChildIdx >= 0) and (ChildIdx < ParentArr.Count) then
      ParentArr.Delete(ChildIdx);
  end;
end;

封装完成后直接调用DeleteJsonPath(Json, 'Level1.Level2.Level3')即可实现按路径删除节点。


2. 从节点反向获取JsonPath的实现

组件本身没有内置反向路径拼接能力,你可以利用TJsonValue自带的Owner属性格式遍历到根节点,逐层拼接路径,生成的路径格式和组件原生Path属性完全兼容,比解析JSON时手动拼接的维护成本更低:

function GetJsonNodePath(Node: TJsonValue): string;
var
  CurrentNode: TJsonValue;
  ParentNode: TJsonValue;
  ParentObj: TJsonObject;
  ParentArr: TJsonArray;
  Segment: string;
  i: Integer;
begin
  Result := '';
  CurrentNode := Node;
  while Assigned(CurrentNode.Owner) do
  begin
    ParentNode := CurrentNode.Owner;
    Segment := '';
    if ParentNode is TJsonObject then
    begin
      ParentObj := TJsonObject(ParentNode);
      for i := 0 to ParentObj.Count - 1 do
      begin
        if ParentObj.Values[i] = CurrentNode then
        begin
          Segment := ParentObj.Names[i];
          Break;
        end;
      end;
    end
    else if ParentNode is TJsonArray then
    begin
      ParentArr := TJsonArray(ParentNode);
      for i := 0 to ParentArr.Count - 1 do
      begin
        if ParentArr.Items[i] = CurrentNode then
        begin
          Segment := IntToStr(i);
          Break;
        end;
      end;
    end;
    if Segment = '' then Break;
    if Result = '' then
      Result := Segment
    else
      Result := Segment + '.' + Result;
    CurrentNode := ParentNode;
  end;
end;

调用该方法传入任意JSON节点实例,即可返回标准点分隔格式的JsonPath字符串,不需要手动维护路径拼接规则。


内容的提问来源于stack exchange,提问作者Bill F

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 01:30:02