4

如果我的帖子格式不正确或没有遵循指南,那么论坛的新手非常抱歉。我会很快“明白”的。所以这是我的问题。看看下面的代码。我已经删除了几乎所有无关的部分,以将注意力集中在一个关键行上——

LParts:=LJsonObj.Get('parts').JsonValue;

我在顶部 (Const) 上有一些 JSON 格式的数据,这些数据已经过测试有效。当我尝试解析它时,它在运行时失败(编译时很好)。我已将所有这些都简化为更小且更易于处理的东西。

当我在调试器中启动它时,这一切似乎都是有效的,但是即使为 Nil 值添加了测试也不会在我对问题的理解中产生太大的影响。

我希望有人知道问题可能是什么。这是代码片段:

program ReadJSONConsoleApp;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  DBXJSON,
  System.SysUtils;


Const
StrJson=
'{' +
'    "response": {' +
'        "distributor": {' +
'            "id": 1538,' +
'            "name": "Arrow Electronics",' +
'            "authorized": true,' +
'            "logoUrl": "this is normally a URL but I cut it out"' +
'        },' +
'        "parts": [' +
'            {' +
'                "manufacturer": "National Semiconductor",' +
'                "part": "LM741WG/883",' +
'                "description": "OP Amp Single GP ±22V 10-Pin CFPAK Tray",' +
'                "price": [' +
'                    {' +
'                        "quantity": 0,' +
'                        "price": 65,' +
'                        "currency": "USD"' +
'                    }' +
'                ],' +
'                "stock": 88,' +
'                "lastUpdated": "2013-11-04 18:27:16 UTC"' +
'            },' +
'            {' +
'                "manufacturer": "National Semiconductor",' +
'                "part": "LM741W/883",' +
'                "description": "OP Amp Single GP ±22V 10-Pin CPAK Rail",' +
'                "price": [' +
'                    {' +
'                        "quantity": 0,' +
'                        "price": 40.5,' +
'                        "currency": "USD"' +
'                    }' +
'                ],' +
'                "stock": 1464,' +
'                "lastUpdated": "2013-11-04 18:27:16 UTC"' +
'            },' +
'            {' +
'                "manufacturer": "Texas Instruments",' +
'                "part": "LM741CH",' +
'                "description": "OP Amp Single GP ±18V 8-Pin TO-99 Box",' +
'                "price": [' +
'                    {' +
'                        "quantity": 0,' +
'                        "price": 5.22,' +
'                        "currency": "USD"' +
'                    }' +
'                ],' +
'                "stock": 95,' +
'                "lastUpdated": "2013-11-04 18:27:16 UTC"' +
'            }' +
'        ]' +
'    }' +
'}';

procedure ParseJson;
var
  LJsonObj  : TJSONObject;
  LJPair    : TJSONPair;
  LParts    : TJSONValue;
  LPart     : TJSONValue;
  LItem     : TJSONValue;
  LIndex    : Integer;
  LSize     : Integer;
begin
    LJsonObj    := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(StrJson),0) as TJSONObject;
  try
     LParts:=LJsonObj.Get('parts').JsonValue;
     {LSize:=TJSONArray(LParts).Size;
     for LIndex:=0 to LSize-1 do
     begin
      LPart := TJSONArray(LParts).Get(LIndex);
      LJPair   := TJSONPair(LPart);
      Writeln(Format('Part Name %s',[LJPair.JsonString.Value]));
        for LItem in TJSONArray(LJPair.JsonValue) do
        begin
           if TJSONPair(LItem).JsonValue is TJSONFalse then
            Writeln(Format('  %s : %s',[TJSONPair(LItem).JsonString.Value, 'false']))
           else
           if TJSONPair(LItem).JsonValue is TJSONTrue then
            Writeln(Format('  %s : %s',[TJSONPair(LItem).JsonString.Value, 'true']))
           else
            Writeln(Format('  %s : %s',[TJSONPair(LItem).JsonString.Value, TJSONPair(LItem).JsonValue.Value]));
        end;
     end; }
  finally
     LJsonObj.Free;
  end;
end;

begin
  try
    ParseJson;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

再次感谢您,感谢您对我的耐心。

亲切的问候,

伊乔

4

1 回答 1

4

您用于解析 JSON 响应的代码与 JSON 字符串的结构无关。首先推荐阅读JSON文档,很容易理解。

试试这个带有注释的示例代码

uses
  DBXJSON,
  System.SysUtils;


Const
StrJson=
'{' +
'    "response": {' +
'        "distributor": {' +
'            "id": 1538,' +
'            "name": "Arrow Electronics",' +
'            "authorized": true,' +
'            "logoUrl": "this is normally a URL but I cut it out"' +
'        },' +
'        "parts": [' +
'            {' +
'                "manufacturer": "National Semiconductor",' +
'                "part": "LM741WG/883",' +
'                "description": "OP Amp Single GP ±22V 10-Pin CFPAK Tray",' +
'                "price": [' +
'                    {' +
'                        "quantity": 0,' +
'                        "price": 65,' +
'                        "currency": "USD"' +
'                    }' +
'                ],' +
'                "stock": 88,' +
'                "lastUpdated": "2013-11-04 18:27:16 UTC"' +
'            },' +
'            {' +
'                "manufacturer": "National Semiconductor",' +
'                "part": "LM741W/883",' +
'                "description": "OP Amp Single GP ±22V 10-Pin CPAK Rail",' +
'                "price": [' +
'                    {' +
'                        "quantity": 0,' +
'                        "price": 40.5,' +
'                        "currency": "USD"' +
'                    }' +
'                ],' +
'                "stock": 1464,' +
'                "lastUpdated": "2013-11-04 18:27:16 UTC"' +
'            },' +
'            {' +
'                "manufacturer": "Texas Instruments",' +
'                "part": "LM741CH",' +
'                "description": "OP Amp Single GP ±18V 8-Pin TO-99 Box",' +
'                "price": [' +
'                    {' +
'                        "quantity": 0,' +
'                        "price": 5.22,' +
'                        "currency": "USD"' +
'                    }' +
'                ],' +
'                "stock": 95,' +
'                "lastUpdated": "2013-11-04 18:27:16 UTC"' +
'            }' +
'        ]' +
'    }' +
'}';

procedure ParseJson;
var
  LJsonObj  : TJSONObject;
  LRoot, LParts    : TJSONValue;
  LPart     : TJSONValue;
  LItem, LPrice     : TJSONValue;
  LIndex    : Integer;
  LSize     : Integer;
begin
    LJsonObj    := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(StrJson),0) as TJSONObject;
  try
     //get the root element
     LRoot:=LJsonObj.Get('response').JsonValue;
     // get the "parts" element
     LParts:=TJSONObject(LRoot).Get('parts').JsonValue;


     LSize:=TJSONArray(LParts).Size;
     //iterate over the "parts"
     for LIndex:=0 to LSize-1 do
     begin
      //extract the value of each pair
      LPart    := TJSONArray(LParts).Get(LIndex);
      LItem:=TJSONObject(LPart).Get('manufacturer').JsonValue;
      Writeln(Format('%s : %s',['manufacturer', LItem.Value]));
      LItem:=TJSONObject(LPart).Get('part').JsonValue;
      Writeln(Format('%s : %s',['part', LItem.Value]));
      LItem:=TJSONObject(LPart).Get('description').JsonValue;
      Writeln(Format('%s : %s',['description', LItem.Value]));

      //the price is an array, so we need a little more of work
      LItem:=TJSONObject(LPart).Get('price').JsonValue;
      LPrice:=TJSONObject(TJSONArray(LItem).Get(0)).Get('quantity').JsonValue;
      Writeln(Format('  %s : %s',['quantity', LPrice.Value]));

      LPrice:=TJSONObject(TJSONArray(LItem).Get(0)).Get('price').JsonValue;
      Writeln(Format('  %s : %s',['price', LPrice.Value]));

      LPrice:=TJSONObject(TJSONArray(LItem).Get(0)).Get('currency').JsonValue;
      Writeln(Format('  %s : %s',['currency', LPrice.Value]));

      LItem:=TJSONObject(LPart).Get('stock').JsonValue;
      Writeln(Format('%s : %s',['stock', LItem.Value]));
      LItem:=TJSONObject(LPart).Get('lastUpdated').JsonValue;
      Writeln(Format('%s : %s',['lastUpdated', LItem.Value]));
      Writeln;
     end;
  finally
     LJsonObj.Free;
  end;
end;

begin
  try
    ParseJson;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
于 2013-11-05T00:21:30.603 回答