Delphi-在运行时解析JSON数据时发生访问冲突 [英] Delphi - Access Violation on Parsing JSON Data @ Run Time

查看:103
本文介绍了Delphi-在运行时解析JSON数据时发生访问冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

论坛的新手,如果我的帖子格式不正确或未遵循准则,我们深表歉意.我会尽快得到它.所以这是我的问题.看看下面的代码.我删除了几乎所有无关紧要的部分,以将注意力集中在一条关键线上-

New to the forums so apologies if my posts are not well formatted or following the guidelines. I'll 'get it' quickly. So here's my issue. Have a look at the code below. I have removed almost all of the extranneous bits to focus attention on one key line --

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

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

I have some JSON formatted data along the top (Const) that has been tested to be valid. When I attempt to parse it, it fails at run time (compile time is fine). I've reduced all of this to something smaller and more manageable to deal with.

当我在调试器中启动它时,这一切似乎都是有效的,但是即使添加了针对Nil值的测试,对我对问题的理解也无济于事.

When I launch this in the debugger, it all seems valid, yet even having added tests for Nil values doesn't yield much in my understanding of the problem.

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

I'm hoping someone knows what the issue might be. Here's the code snippet:

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.

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

Thank you again and thanks for being patient with me.

亲切的问候,

EEJoe

推荐答案

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

The code which you are using to parse the JSON response is not related to the structure of your JSON string. First recommendation is read the JSON documentation, is very easy to understand.

请尝试使用带有注释的示例代码

Try this sample code with comments

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.

这篇关于Delphi-在运行时解析JSON数据时发生访问冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆