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 |
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 |
Hello Sven, Thanks for that hint! It looks like exactly what I need ☺️ Best regards, Marc Am 24.05.2017 16:38 schrieb "Sven Van Caekenberghe" <[hidden email]>: Marc, |
In reply to this post by Sven Van Caekenberghe-2
> 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 > > |
In reply to this post by Pharo Smalltalk Users mailing list
mark what you can also do is to generate the classes from the json we did that for certain libraries. Stef On Wed, May 24, 2017 at 4:20 PM, Marc Hanisch via Pharo-users <[hidden email]> wrote:
|
Free forum by Nabble | Edit this page |