lazarus - TJSONData路径存在

时间:2016-07-05 20:14:10

标签: json delphi lazarus

我正在尝试使用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"
        }
    ]

}

但数据不相等,例如JohnmessageDavid没有。

注意:如果我尝试为每个人阅读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;

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

2 个答案:

答案 0 :(得分:1)

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

其次,FindPath()如果找不到指定的路径,则返回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&#39;文档了解更多详情:

Reference for unit 'fpjson'

答案 1 :(得分:0)

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

因此,在尝试访问任何成员之前,不是无条件地使用FindPath()的返回,而是将结果分配给适当类型的某个中间变量并测试 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 ==&gt; optional),因此使用我的实现的等价物将类似于:< / p>

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测试我的库,所以这个代码仅供感兴趣/ Delphi开发人员使用,而不是作为建议(参见上面的初始代码片段)。