从 TJsonObject 中移除 Pair

Remove Pair from TJsonObject

{
  "Test":{
    "A":{
      "ins":{
        "type":"pac",
        "id":{
          "values":{
            "test_number":"156764589",
            "val":"abcde",
            "val_2":"gggg",
            "val_3":"jjjj"
          },
          "verif":{
          },
          "bool":"INSTR"
        }
      }
    },
    "resp":{
      "image":"include"
    },
    "op":{
      "id":{
        "meth":"def"
      }
    }
  }
}

我正在记录一个已发送的 http 请求,出于隐私考虑,我需要从 TJsonObject 中删除一个元素。但是,当我尝试删除密钥并记录它时,它仍然存在

TJSONObject *obj = (TJSONObject*) TJSONObject::ParseJSONValue(TEncoding::UTF8->GetString(id_http_wrap.msg));
obj->RemovePair("Test.A.ins.type.id.values.test_number");

这应该可以解决问题:

implementation

uses
  System.IOUtils, System.JSON;

procedure DoSomeJSONStuff;
var
  jsonstr: string;
  jo, jochild: TJSONObject;
begin
  jsonstr := TFile.ReadAllText('C:\Temp\example.json', TEncoding.UTF8);
  jo := TJSONObject.ParseJSONValue(jsonstr) as TJSONObject;
  if (jo <> nil) then begin
    try
      jochild := ((((jo.GetValue('Test') as TJSONObject).GetValue('A') as TJSONObject).GetValue('ins') as TJSONObject).GetValue('id') as TJSONObject).GetValue('values') as TJSONObject;
      jochild.RemovePair('test_number');
      TFile.WriteAllText('C:\Temp\example_changed.json', jo.ToString, TEncoding.UTF8);
    finally
      jo.Free;
    end;
  end;
end;

请记住,使用 UTF-8 编码的 TFile.ReadAllText 和 WriteAllText 实际上是 UTF-8-BOM。

当然你可以把代码格式化一下更好

首先,你的路径是错误的。 type 不在通往 test_number 的路径中。正确的应该是:

obj->RemovePair("Test.A.ins.id.values.test_number");

但据我所知,RemovePair 无法解析。你必须使用 FindValue:

// Cast helper:
TJSONObject* ToTJSONObject(TJSONValue* v) {
    auto obj = dynamic_cast<TJSONObject*>(v);
    if(!obj) throw Exception("v is not a TJSONObject");
    return obj;
}

auto obj = ToTJSONObject(TJSONObject::ParseJSONValue(...));

TJSONPair* removed =
    ToTJSONObject(obj->FindValue("Test.A.ins.id.values"))->RemovePair("test_number");

if(removed) {
    // successfully removed:         removed->ToString()
    // the resulting JSON document:  obj->ToString()
}

在 kbmMW 中可以这样做:

const JSON: string =
'{'+
'  "Test":{'+
'    "A":{'+
'      "ins":{'+
'        "type":"pac",'+
'        "id":{'+
'          "values":{'+
'            "test_number":"156764589",'+
'            "val":"abcde",'+
'            "val_2":"gggg",'+
'            "val_3":"jjjj"'+
'          },'+
'          "verif":{'+
'          },'+
'          "bool":"INSTR"'+
'        }'+
'      }'+
'    },'+
'    "resp":{'+
'      "image":"include"'+
'    },'+
'    "op":{'+
'      "id":{'+
'        "meth":"def"'+
'      }'+
'    }'+
'  }'+
'}';

procedure TForm1.Button1Click(Sender: TObject);
var
   str:TkbmMWJSONStreamer;
   js,o:TkbmMWONCustomObject;
begin
     str:=TkbmMWJSONStreamer.Create;
     try
        js:=str.LoadFromUTF16String(JSON);
        o:=js.Path('Test/A/ins/id/values');
        if o.IsObject then
           TkbmMWONObject(o).Remove('test_number');
        Memo1.Lines.DelimitedText:=JSON;
        Memo2.Lines.DelimitedText:=str.SaveToUTF16String(js);
     finally
        str.Free;
     end;
end;