9.03.2014 A Simple JSON Parsing Example

Can't get enough of JSONs? Crunch some JSON data with this simple code!


JSON is a very common data format now a days, especially in various APIs. JSON or JavaScript Object Notation is a comma seperated data writing format. It is easy for the humans to read & write. It is easy for the machines to read & write. So it is a d@mn good format to put data in. See this example and you'll get the idea:

{
    "name1": value1,
    "name2": value2
}

As you can see, the value is written in quotes followed by a colon (:) sign, followed by a value is the basic structure. It is an example straight from the wiki. Here's another one from the wiki:

{"user":
    {    "userid": 1900,
        "username": "jsmith",
        "password": "secret",
        "groups": [ "admins", "users", "maintainers"]
    }
}

Seems complex at first. But as you can see, it is very straight forward. It is fairly simple, especially when compared to other text based data structures such as XML. Oh boy! Newbies have a nightmare writing XML codes. Those sharp-edged, pointy angle brackets are not something which is easy to their eyes!

But JSON is very simple. It can be broke down into several points:

- When you want to write a group of data you use a curly brackets ( { } ).
- The whole data is considered as a group and so it is enclosed in 2 curly brackets, always. (Even when there is only one name/value pair.)
- Then you write names of values and then values. You separate them with a colon (:)
- If you write a string anywhere, use double quotes ( " " ). And if you write numeric data, don't use it.


That's it! So simple.

How about a simple pascal example to go with it? Okey, let's get to it!

2 Lines Code Example

Start Lazarus. Create a new Application Project (Project -> New Project -> Application -> OK).

Switch to Code View (F12). Add fpjson and jsonparser to the uses. These are units which has functions to work with JSON.

uses
  ..., fpjson, jsonparser;

Now switch to Form View (F12). Now double click the form and enter the following code:

procedure TForm1.FormCreate(Sender: TObject);
var
  json: String;
  J: TJSONData;
begin
  // We hold our json data in a string.
  // The variable "json" is a string type.
  // We can also use TJSONStringType instead of string.
  json:='{"user":'+
    '{    "userid": 1900,'+
        '"username": "jsmith",'+
        '"password": "secret",'+
        '"groups": [ "admins", "users", "maintainers"]'+
    '}'+
  '}';

  // We send our JSON data to TJSONData. This is line 1 of our code.
  J:=GetJSON(json);

  // We show the username from the data
  // FindPath returns TJSONData
  // So we use .AsString to convert it to string. This is line 2.
  Caption :=  J.FindPath('user.username').AsString;
end;

So you see it! We have a perfectly working example of JSON parsing with barely 2 lines of code. Lazarus is that good!

Now go ahead and Run the project (F9 or Run-> Run). You will see jsmith in the titlebar of your form. Neat!

Extending the example

We have seen a basic example. Now its time to extend it. We will build a program to let us paste json data in it and query different paths. This will help us test various API responses and get a good idea which path will work best for us.

So, go ahead and create a new Application Project (Project -> New Project -> Application -> OK). That's easy!

Now, as before, add fpjson and jsonparser to the uses:

uses
  ..., fpjson, jsonparser;

Switch to Form view and draw 2 TMemo. Memo1 should be on the left and Memo2 should be on the right. Set their ScrollBars to ssAutoVertical in order for them to be scrollable. You can use TGroupBox to decorate any way you like.

Now draw a TEdit and a TButton on the form. They should appear as Edit1 and Button1. Change their name as edtPath and btnParse to have a identifiable layout. Use any TLabels if you think they are appropriate, even a TGroupBox is good. My form looks like this:


You can set some default values. For that change the Memo1's Lines as the code below:

{"user":
    {    "userid": 1900,
        "username": "jsmith",
        "password": "secret",
        "groups": [ "admins", "users", "maintainers"]
    }
}

Set edtPath's Text property as: user.username
And blank out the Memo2's Text property.

And you may want to change the Form's Caption as well, that's no surprise!

Now your form may look like this:


Now double click the button and enter:

procedure TForm1.btnParseClick(Sender: TObject);
var
  J: TJSONData;
begin
  // Parse JSON Data to TJSONData
  J:=GetJSON(Memo1.Text);
  // Get the value for the path in edtPath
  Memo2.Text:=J.FindPath(edtPath.Text).AsString;
end;

Again, only 2 lines of code does the trick!

Now Run it (F9 or Run-> Run).




Noe click the Parse button. You should see jsmith in the Result. It works graciously. But what if the path does not exist? Try out with some random path and you will see an SIGSEGV error.

To fix it, add a simple try ... except block in your code, like this:

procedure TForm1.btnParseClick(Sender: TObject);
var
  J: TJSONData;
begin

  try
    // Parse JSON Data to TJSONData
    J:=GetJSON(Memo1.Text);
    // Get the value for the path in edtPath
    Memo2.Text:=J.FindPath(edtPath.Text).AsString;

  except
    on E: Exception do ShowMessage('Error finding path!');

  end;

end;

You will not see the message when running from inside Lazarus. To test it, save the project somewhere and run it from Lazarus, then double click the .exe from the explorer. Then enter a random string to test if the message box appears.

Now you are ready parse some serious JSON goods!

If you want to learn more advanced ways to parse you will find some other examples here: http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-json/examples/


Download Sample Code ZIP

You can download the above tutorial project's example source code from here
Or here: http://bit.ly/json-parser
Size: 720 KB
The package contains compiled executable EXE file.

Ref:
http://wiki.freepascal.org/JSON
http://www.freepascal.org/docs-html/fcl/fpjson/index.html
http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/packages/fcl-json/examples/

7 comments:

Unknown said...

Hello. Thank you for this great article. I need to send a URL in my application (Win32), the remote server will reply with a JSON response. How do I get Lazarus to send the URL? and I how do I "catch" the response for parsing?

Thank you,

sb

Stephen Eaton said...

Thanks for the great article, has helped me.

Pratama Aditya said...

TQ

Unknown said...

hi, how would you parse:
{"A":{"present":0},"B":{"present":1}}
thank you

Adnan Shameem said...

@Tudor Hulban
You can try something like this:
----
uses
..., fpjson, jsonparser;
...
procedure TForm1.FormCreate(Sender: TObject);
var
json: String;
J: TJSONData;
begin

json:='{"A":{"present":0},"B":{"present":1}}';
J:=GetJSON(json);

Caption := 'Is A present? '+J.FindPath('A.present').AsString;
Caption := Caption + '. Is B present? '+J.FindPath('B.present').AsString;

end;
----
Good luck. Hope it helps.

Sallecta said...

Very helpful tutorial, big thanks!

(please check typo, paragraph "Noe click the Parse button. You should see ..." should be "Now click...")

Umar Sear said...

hands down the best article I found regarding JSON and pascal. Thank you.

 
Copyright 2013 LazPlanet
Carbon 12 Blogger template by Blogger Bits. Supported by Bloggermint