0

I was trying to parse JSON from a website using Delphi XE2 and following code suggested in this thread here. When I implement the code exactly as it appears in the respondents post, it works, but when I implement something almost identical in mine, I get an access violation at a line that read:

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

And it fails (when running it) with an AV every time (compiles ok, just won't run). I have simplified my code and below is a snippet that I would expect to work. Afterall, this is a copy and paste of other, working code.

I would be really grateful if someone could have a look below and let me know why mine doesn't work but the code in the referenced post does. I am puzzled largely because when I debug it, it looks like it should be working and there is little debug info to go off of.

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.0,' +
'        "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"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741CN",' +
'      "description" : "OP Amp Single GP ±18V 8-Pin PDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 0.3633,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 4320,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.22,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 3458,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.71,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 0,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741CN/NOPB",' +
'      "description" : "OP Amp Single GP ±18V 8-Pin PDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 0.2977,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 6486,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741J",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin CDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 7.21,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 362,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H/NOPB",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.22,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 1378,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741J/883",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin CDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 11.8,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 989,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H/883",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Tray",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 15.74,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 4252,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741CHNOPB",' +
'      "description" : "OP Amp Single GP ±18V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.22,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 785,' +
'      "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.
13
  • Just a side note: the JSON data in this has been heavily edited to make the post shorter. I can post the full length JSON data if this doesn't suffice to recreate the issue. Commented Nov 4, 2013 at 21:31
  • 2
    Found the problem... LJsonObj is nil after you call TJSONObject.ParseJSONValue... figuring out why now and will post an answer for you! Commented Nov 4, 2013 at 21:47
  • 1
    Your JSON string doesn't seem to want to parse... even though it looks properly formatted. I'm looking deeper into that now. Commented Nov 4, 2013 at 22:00
  • 1
    @DoubleE, You are not parsing correctly the JSON string, post a new question and I will help you :) Commented Nov 4, 2013 at 23:38
  • 1
    @TLama - Thanks mate, just did that! And thanks for the help! Commented Nov 5, 2013 at 0:01

1 Answer 1

1

The call to ParseJSONValue returns nil. The documentation calls this out:

ParseJSONValue returns the JSON value corresponding to the parsed data, or null if the parsing fails.

You fail to check for such a condition, and the access violation is the inevitable consequence. Unless your JSON is pre-validated, you'll want to check its validity.

You can double check this yourself by pasting your JSON into an online validator. For example: http://jsonlint.com/ Do this and you will see that the JSON is not valid.

Here's some valid JSON:

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.0,' +
'        "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"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741CN",' +
'      "description" : "OP Amp Single GP ±18V 8-Pin PDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 0.3633,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 4320,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.22,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 3458,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.71,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 0,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741CN/NOPB",' +
'      "description" : "OP Amp Single GP ±18V 8-Pin PDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 0.2977,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 6486,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741J",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin CDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 7.21,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 362,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H/NOPB",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.22,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 1378,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741J/883",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin CDIP Rail",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 11.8,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 989,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741H/883",' +
'      "description" : "OP Amp Single GP ±22V 8-Pin TO-99 Tray",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 15.74,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 4252,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }, {' +
'      "manufacturer" : "Texas Instruments",' +
'      "part" : "LM741CHNOPB",' +
'      "description" : "OP Amp Single GP ±18V 8-Pin TO-99 Box",' +
'      "price" : [ {' +
'        "quantity" : 0,' +
'        "price" : 5.22,' +
'        "currency" : "USD"' +
'      } ],' +
'      "stock" : 785,' +
'      "lastUpdated" : "2013-11-04 18:27:16 UTC"' +
'    }' +
'    ]' +
'  }' +
'}';

Whether or not it's what you want, I cannot be sure.

Plug this constant into your program, and it will advance further, but then fail on the Get('parts') line. That also returns nil and you get another AV when you try to read the JsonValue property.

Not knowing exactly what you are doing, I cannot tell you how to debug the entire code. What you do need to do is to start taking note of the fact that these JSON methods and properties may return nil. So check for that before you attempt to access methods and properties on a nil reference.

My other piece of advice is to put the JSON into a file so that it is easier to work with. Building up constants like this makes debugging very tricky.

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you. Must have crossed in the ether as I just modified the post with correctly formatted JSON data. Still the application encounters an AV. This time in the call to ParseJson. Trying to track this down now.
There is no method called ParseJSON. That's your main function. The problem that you asked about was due to invalid JSON. The next problem is, well, the next problem. Since we don't know for sure what the right JSON is, and what you are trying to do, we cannot debug your entire program. What we can do is answer the question that you asked.
Not sure I understand your response. I replaced the source code with valid JSON in the original post (something I mentioned when I originally posted, if you see the first comment) and the program still generates an AV. Using the valid JSON. The issue is not simply invalid JSON. That was something I mentioned may be a problem with the posted code as I was removing things for brevity's sake.
Incidentally, the issue all along has been failing on the Get() line. It's in the subject of the post.
You posted a program and asked why it produced an access violation. And I answered that question. The code that you posted produced an AV because the JSON was invalid. You can execute the code in the post and observe that LJsonObj is nil. So yes, the call to Get fails because the subject of the method call is nil. And that's because the JSON is not valid.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.