We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I've just been given a 2.5MB JSON file example. The contents have about 5 levels of item, some with long lists of items. Ideally the function I want is: Return the heirarchial name a.b.c... of the item that has 'name' (input) as the value of a string called "text".
I've tried the JSON Load/save Array/Object functions in the help, but nothing leads me towards how to deal with a recursive tree structure. The examples contain the names of the structures, I'd prefer it read them from the file.
Answers
post what you've done and some test data (not the whole file, given the size). and format it nicely (highlight the code, press ctrl-o)
generally it's expected that you know the shape of the data that you're receiving.
This could be relevant but not the final answer: http://crunchify.com/in-java-how-to-flatten-or-unflatten-complex-json-objects-into-flat-map-like-structure/
You might need to do some reverse engineering and handle array cases and degenerate results (request values that has multiple entries in your json file).
Kf
@koogs, what I've done is literally tried the help examples, and the data isn't mine to post. @kfrajer, spent some while looking at that, looked more involved than I expected. Then realised that as the given file is perfectly indented, what little I want is available by finding the item, then going back up the file watching the indents decrease. Thanks and sorry that wanting it now is making me use the quick crude way.
Test data, data like the data, it doesn't have to be THE Data, just the same shape. Without it everything is too theoretical.
the source is here: https://github.com/processing/processing/blob/master/core/src/processing/data/JSONObject.java
annoyingly there is a map inside it, but it's private and therefore unreadable.
i had a quick look and tried this, recursively parsing each element of the json and placing it in a map as i went, like you would a directory tree. BUT it doesn't work - parseJSONObject chokes on arrays, in a way you can't catch and handle. and because you don't know whether the object is an array or an object before you parse it then you are stuck. (this is what i mean about knowing the shape of the json, it would be trivial then. the general case is much harder.)
will have a better look at it later, but i have things to do...
(the source is a bit enlightening, they are parsing the json themselves rather than using one of the standard libraries to do it)
this is false, it throws a runtimeexception. so that's good.
the next problem is that get(int) for arrays is private... at least in the version of processing i'm currently using (was changed in oct 2016). downloading new version as i type...
this puts all the data into a hashmap, keyed by hierarchical name. haven't tested it beyond the data in the file. and 2.5MB might be too much for it but...
@Koogs, Now I've had another look at the JSON parsing. I'm shocked to find it's over two months ago, anyway... Your program starts to work, then exceptions. I've made a small example file and posted, above.
The exception is on line 59, ClassCastException: java.lang.String cannot be cast to processing.date.JSONObject.
Taking the line apart: (JSONObject)array.get(i) does not like the text .F_CV .
I've enabled your print statements and added some. Don't understand the order of processing, seems not in order down the input file. Difficult to tell if this is the first F_CV that it's arrived at.
Just realised that I don't need the F_CV and if I chop them out of the source file (regex in N++) it runs through cleanly and gives a straight list of all the items, with hierarchical name - just what I was asking for in the first place :) wow thanks. I don't need the F_CV and could remove it on the fly, but a purist would want to understand and fix.
The map output at the end is in a strange order, not the same as the input, not alpha. It probably doesn't matter but I think I want it alpha at each level. I'll look at the listing function. (And I've read+used HashMap for the first time - good.)
Thanks again, Richard.
Will have a look later when I'm awake. But, yes, maps aren't stored in any order, they are meant to allow O(1) lookup, not to be printed as a list. It's easy enough to order them alphabetically by key though.
(Actually a TreeMap should preserve the order and is a more obvious choice given the input is a tree)
these are the only arrays that don't contain json objects, which is why it's falling over.
anyway, fixed (alphabetical also):
it expects the json to be in a file
data.json
in the usual data directory under the sketch.oh, empty arrays are omitted...
Koogs thanks for the code and the post, very useful. I'm creating interface to the Microsoft Azure Cognitive Services Face API raw working code on Gist.
I'm wondering if and how I can iterate over certain base keys?
My output is now like:
faceAttributes.age = 38.3 faceAttributes.emotion.anger = 0.0 faceAttributes.emotion.contempt = 0.001 faceAttributes.emotion.disgust = 0.0 faceAttributes.emotion.fear = 0.0 faceAttributes.emotion.happiness = 0.0 faceAttributes.emotion.neutral = 0.888 faceAttributes.emotion.sadness = 0.11 faceAttributes.emotion.surprise = 0.0 faceAttributes.facialHair.beard = 0.4 faceAttributes.facialHair.moustache = 0.5 faceAttributes.facialHair.sideburns = 0.5 faceAttributes.gender = male faceAttributes.glasses = NoGlasses faceAttributes.hair.bald = 0.02 faceAttributes.hair.hairColor[0].color = brown faceAttributes.hair.hairColor[0].confidence = 1.0
... etc.I'd like to iterate over all the emotions and display the values. How would I do that? Some idea's or pointers to documentation would be welcome.
https://forum.processing.org/two/discussion/21503/json-how-to-get-heirarchical-names-from-file
(Sorry!)
Your question is more about Java maps than json, but a simple string compare around line 40 should do it.
(line 40 of my code above, that is)
Clear. I thought maybe something is build in Java treemaps, but I'll work with compare then.
the other way to do this is to pick out the emotion json object before calling my code:
so you actually start parsing two levels into the structure. this requires you to know the structure of the data.