You do have to represent the structure to the depth of the information
you want to extract, but you don't have to enumerate all the fields,
only the ones that contain relevant info. For example, if you wanted
only a list of company symbols, you have to have data structures that
hold the query, results, industry, company (list) and symbol, but you
can ignore created, lang, industry id/name, etc. The JSON unmarshaler
will skip stuff it doesn't find a place for.
I don't see anything wrong with this; it seems totally appropriate for
"real world JSON objects". Really I have no idea how you could even
get around this kind of requirement and still call it JSON parsing. If
you only want very particular pieces of data at the very bottom of a
deep hierarchy, consider a regex.
then you could dive down into the json structure
and still get the benefits of unmarshalling to structs.
JSON can't unmarshal into private fields because they are private. It
doesn't have any special permissions. In order to get it to work, you
have to export the fields you need to unmarshal into.
Thanks, I didn't understand what "export fields" meant.
Mere guesswork: []main.industry is a slice, so you should
be trying to unmarshall an array into it, not any old object.
(Should the message be more explicit about the entity it's
trying to unmarshall?)
Chris
--
Chris "allusive" Dollin
if it's changed to be an array, the unmarshalling works.
if this is common practice in JSON encodings, it would
be possible to change json.Unmarshal so that it is
liberal enough to unmarshal a singleton object into
an array.
as it is currently, your only option is to change the
type of Sector.Industry to interface{} and do the extraction
manually.
i still think that my earlier suggestion would be useful,
particularly when the top levels of the JSON data
are not very rigidly defined.
On 27 November 2010 15:23, m <phill...@gmail.com> wrote:
yes!
One idea I had: register a type with the json package, and then when
unmarhsalling into a value of type interface{}, json will look at its
set of registered types for one that matches the provided fields and
initialise a value of that type, instead of a map[string]interface{}.
For example:
type Foo struct {
Bar int
Baz string
}
const s = `{"Bar": 12, "Baz": "a string"}`
func main() {
json.Register(Foo{})
var v interface{}
json.Unmarshal([]byte(s), &v)
_ := v.(Foo) // this should work
}
This would make much of my code simpler. Does that seem useful to anyone else?
Andrew
Yes, exactly.
My workaround thus far has been to create a shim object:
type Shim struct {
Foo *Foo
Bar *Bar
}
And then when generating the JSON, I put the actual data one level down:
{"Foo": { foo object contents }}
or
{"Bar": { bar object ... }}
Then it's just an if shim.Foo == nil test, but it would be much more
elegant to use a type switch.
Andrew