Login  Register

Re: How to query a JSON

Posted by Sven Van Caekenberghe-2 on May 24, 2017; 7:27pm
URL: https://forum.world.st/How-to-query-a-JSON-tp4948175p4948185.html


> On 24 May 2017, at 17:09, Marc Hanisch <[hidden email]> wrote:
>
> Hello Sven,
>
> Thanks for that hint! It looks like exactly what I need ☺️

Here is a quick example using the new JSON Feed format (https://jsonfeed.org).

json := ZnClient new
  systemPolicy;
  url: 'https://daringfireball.net/feeds/json'; 
  accept: ZnMimeType applicationJson;
  contentReader: [ :entity | NeoJSONObject fromString: entity contents ];
  get.

json items collect: #title.
json items collect: [ :each | each title -> each url ].

Note how you can just pretend that the objects understand #items, #title or #url.

> Best regards,
> Marc
>
> Am 24.05.2017 16:38 schrieb "Sven Van Caekenberghe" <[hidden email]>:
> Marc,
>
> > On 24 May 2017, at 16:20, Marc Hanisch via Pharo-users <[hidden email]> wrote:
>
> > Hello,
> >
> > is there a way to query a JSON with a path (JSONPath or some custom format)?
> >
> > I want to query an API and collect the JSON responses, which I need to iterate over to extract some data. Modelling the JSON structure as classes would be too much overhead, I think. I just want to collect some values...
> >
> > Thanks in advance,
> > Marc
>
> Normally, when you use the NeoJSON package and you don't do any mapping, you get Dictionaries and Arrays back.
>
> There is however also something called NeoJSONObject, a Dictionary subclass that has some API that is quite fluent and that does include path style access.
>
> To get started, use NeoJSONObject class>>#fromString: as parser.
>
> Here is the class comment:
>
> ===
> I am NeoJSONObject.
> I am a Dictionary.
>
> I behave more like a JavaScript object. I return nil for missing keys. I allow any property to be read or set by using a normal accessor message.
>
> The following are equivalent:
>
>         self foo.
>         self at: #foo.
>
> As are the following
>
>         self foo: 1.
>         self at: #foo put: 1.
>
> Except that in the first case, self is returned.
>
> I can optionally be used by NeoJSONReader as mapClass (see #mapClass:).
>
> For output, I act just like my superclass (it is thus not necessary to do any conversions).
>
> Example:
>
>         NeoJSONObject fromString: '{"foo":1,"bar":-2}'.
>         NeoJSONObject new foo: 1; bar: -2.
>         { #x -> 100. #y -> 200 } as: NeoJSONObject.
>         (NeoJSONObject new data: (NeoJSONObject new id: #sensor1; value: 37.5)) asString.
>
> I use JSON as my printed representation. To convert me to JSON, use #printString or #asString.
>
> Additionally, I support path access for nested instances of me, using #atPath: and #atPath:put:
>
> The first is special because it returns nil as soon as a key is missing. The second is special because it creates extra levels (instances of me) as needed to follow the path of keys.
>
>         NeoJSONObject new atPath: #(one two three) put: 42; yourself.
>         NeoJSONObject new atPath: #(one two three) put: 42; atPath: #(one two three).
> ===
>
> HTH,
>
> Sven
>
>