lazarus - TJSONData 路径存在

lazarus - TJSONData path exists

我正在尝试使用 JSON,但我的问题是我找不到任何方法来检查路径是否存在或获取路径列表。

例如,我的应用程序从服务器收到此 JSON:

{
    "ok": true,
    "result":[
        {
            "id": 12,
            "first_name": "David",
            "username": "Fake"
        },
        {
            "id": 13,
            "first_name": "John",
            "username": "sample",
            "message":"test msg"
        }
        ,{
            "id": 13,
            "first_name": "David",
            "username": "Fake",
            "text":"test txet"
        }
    ]

}

但是数据不相等,比如John有一个message但是David没有。

注意:如果我尝试为每个人阅读 message,我会在代码中遇到异常。

这是我的代码:

for i := 0 to jsonDoc.findpath('result').Count - 1 do
begin
  // jsonDoc.findpath('result').Items[i].WHAT IS NEED FOR CHECK ??

  Result[i].text := jsonDoc.findpath('result').Items[i].FindPath('message').AsString; // exception           
end;

请指导我查找路径列表或检查路径是否存在。

我使用 my own JSON implementation,所以不熟悉 Lazarus JSON 的具体实现,但是从您发布的代码来看,FindPath('message') returns NIL 如果指定的路径不存在。

因此,与其无条件地使用 FindPath() 的 return,不如将结果分配给适当类型的某个中间变量,并在尝试之前测试 NIL访问任何成员:

var
   msg: T??;

//...

msg := jsonDoc.findpath('result').Items[i].FindPath('message');
if Assigned(msg) then
    Result[i].text := msg.AsString
else
    Result[i].text := '';  // If necessary

//...

为了比较,我的 JSON 库使用 OptXXX 函数来读取对象上可能不存在的值(Opt ==> 可选),因此等效于使用我的实现是这样的:

var
  jsonResults: TJSONArray;

//..

jsonResults := jsonDoc['result'].AsArray;
for i := 0 to Pred(jsonResults.Count) do
  result[i].Text := jsonResults[i].AsObject.OptString('message');

但是,我还没有使用 FPC/Lazarus 测试我的库,因此此代码仅供 interest/Delphi 开发人员使用,不作为建议(请参阅上面的初始代码片段)。

首先,您对 findPath('result') 的使用非常低效。您应该 调用它一次 并将返回的对象保存到局部变量。

其次,FindPath() returns nil 如果找不到指定的路径,但您没有检查该条件,这就是为什么当 message 丢失。

试试这个:

var
  jsonDoc, r: TJSONData;
  msg: TJSONData;
  I: Integer;
begin
  jsonDoc := ...;
  r := jsonDoc.findpath('result');
  if r <> nil then
  begin
    for i := 0 to res.Count - 1 do
    begin
      msg := res.Items[i].FindPath('message');
      if msg <> nil then
        Result[i].text := msg.AsString
      else
        Result[i].text := '';
    end;
  end;
end;

请阅读 Lazarus 的文档了解更多详情:

Reference for unit 'fpjson'