Miguel E
Miguel E

Reputation: 1326

Accessing inner JSON value

I have the following JSON structure:

concurrence: [
  {
    id: "481-13",
    price: "11.5",
    concurrent: {
      id: 13,
      name: "NAME1",
      price: "11.5"
    }
  },
  {
    id: "481-14",
    price: "12.25",
    concurrent: {
      id: 14,
      name: "NAME2",
      price: "12.25"
    }
  }
]

How can I get the concurrent.id value? I tried to use the FindValue() method listed in the RADStudio documentation, but it doesn't exist (at least in 10.1 Berlin).

I'm accessing the concurrence array like this:

concurrents := product.Get('concurrence').JSONValue as TJSONArray;
for j := 0 to concurrents.Size-1 do
begin
  concurrent := concurrents.Get(j) as TJSONObject;
  json_s := concurrent.Get('id').JsonValue as TJSONString;
  my_id := json_s.Value;
  json_s := concurrent.Get('price').JsonValue as TJSONString;
  my_price := json_s.Value;
  json_s := concurrent.FindValue('concurrent.id') as TJSONString;//NOT WORKING
  my_concurrent_id := json_s.Value;
end;

Is there another way to access the inner concurrent values?

Upvotes: 2

Views: 1452

Answers (3)

Arioch 'The
Arioch 'The

Reputation: 16045

According to http://www.jsoneditoronline.org/ your JSON is malformed.

The correct one would need to be put into curly brackets:

 {
  concurrence: [
    {
      id: "481-13",
      price: "11.5",
      concurrent: {
        id: 13,
        name: "NAME1",
        price: "11.5"
      }
    },
    {
      id: "481-14",
      price: "12.25",
      concurrent: {
        id: 14,
        name: "NAME2",
        price: "12.25"
      }
    }
   ]
  }

With this correction you can just address it as JsonVar['concurrence[0].concurrent.id'] and JsonVar['concurrence[1].concurrent.id']

SuperObject parsing

Using https://github.com/hgourvest/superobject

var
  obj, id: ISuperObject;
  N, M: Integer;
begin
  obj := SO('{ concurrence: [ { id:  ....... ');

  id := obj[ 'concurrence[0].concurrent.id' ];
  if id <> nil then
     N := id.AsInteger;                         //  N <== 13

  M := obj.I[ 'concurrence[1].concurrent.id' ]; //  M <== 14

  obj := nil;
  id := nil;
end;  

The latter option while easier is a bit flaky. Since it can not return nil then it returns default(Integer) zero when the actual value is not found.

This quick parsing syntax also failes with JSON-but-not-JavaScript payloads: https://github.com/hgourvest/superobject/issues/8

Upvotes: 1

Stefan Glienke
Stefan Glienke

Reputation: 21713

Personally I would rather use JsonDataObjects.

Then the code would look like this:

var
  product: TJsonObject;
  concurrents: TJsonArray;
  o: TJsonObject;
begin
  ...
  concurrents := product.A['concurrence'];
  for o in concurrents do
    Writeln(o.O['concurrent'].I['id']);

Upvotes: 1

Ren&#233; Hoffmann
Ren&#233; Hoffmann

Reputation: 2815

You access items of concurrent the same way as every other JSON object.

You just have to get the JSON object itself before. But this is easy:

concurrent_sub:= concurrent.Get('concurrent').JsonValue as TJSONObject;
json_s := concurrent_sub.Get('id').JsonValue as TJSONString;

Upvotes: 6

Related Questions