JSONSmart parsing a whole array and getting each object? - java

An example JSON.
EDIT: I've put it on a pastebin because of how big the file is - http://pastebin.com/wdR2paBp
How would I get an Array of "objects", then iterate through it and get the name (i.e. "minecraft/sounds/dig/sand4.ogg") and the hash from each of these files?
My attempts:
FileReader fr = new FileReader(location.getAbsolutePath());
JSONArray iIndexes = (JSONArray) parser.parse(fr);
I've also tried making Objects a JSONObject then making it a JSONArray then using a for loop to get every object, but I get a NPE or a ClassCast Exception (for the atttempt before this one).

What you have there is a JSON object, not a JSON array. Conceptually, you can treat it as a set of name/value pairs, but according to the JSON specification, the NV pairs are not ordered; i.e. it is a set, not a list.
There is no standard way to turn that JSONObject into a JSONArray. Casting won't work, and the JSONObject doesn't have a method to do the conversion. And certainly, there is no way using JSONSmart to preserve the apparent order of the NV pairs in your source file / string. (Which is a good thing, IMO, because the order shouldn't mean anything.)
If you want to iterate the NV pairs, the best way to do it is to use the entrySet method to get the JSONObject's entries as a Set ... and then iterate the set. (The JSONSmart version of JSONObject is a subclass of HashMap.)
Now if set of entries in "objects" is supposed to be ordered, then you have designed your JSON scheme incorrectly. You should be using a JSON array (using the [...] JSON syntax) and the elements need to be restructured as objects; e.g.
[ {
"name": "realms/lang/de_DE.lang",
"hash": "10a54fc66c8f479bb65c8d39c3b62265ac82e742",
"size": 8112
},
{
"name": "realms/lang/cy_GB.lang",
"hash": "14cfb2f24e7d91dbc22a2a0e3b880d9829320243",
"size": 7347
},
etcetera
]
When you parse that using JSONSmart you will get a JSONArray.

Related

JSON format for a Vector of numbers

I'd like to populate a Java double vector, double dNumber[], from a JSON String. In Java I just have one variable dNumber.
Is there any way I can use one variable in JSON with the list of values. I don't want to create a separate JSON name for each item in the array.
Thanks.
Al
Yes.
A JSON can contain an array of values. The syntax is
{
dNumbers: [ 12.5, 6.8, 3.1415],
[...]
}
More on JSON here

Using JsonPath to extract inhomogeneous list as typed objects

I need to parse json with a list of inhomogeneous "items" i.e. each may have different keys/structure but they share one common key (here called "a") that gives the type of the item.
{
"items":[
{"a":1, "d":2},
{"a":2, "b":{"c":2}}
]
}
One way I thought to do this might be to pick out the json string for each "item" from the list at path "$.items" using something like the following,
List<String> jsonStrings = JsonPath.parse(json).read("$.items");
such that the first string would be '{"a":1, "d":2}' and the second would be '{"a":2, "b":{"c":2}}'. This is so that I can continue to ask questions of the inner bits using JsonPath itself. Is this possible? (The code above fails as JsonPath returns a list of maps instead.)
An alternative solution might be to use a JsonPath "query path" (my term) to return only "items" with e.g. a = 2 as a list of maps - or a list of typed objects that match the nested structure of each item type, (perhaps sharing a super interface containing the type key as a field). Is this possible?
$.items doesn't work because it's not a list of strings. It's an array of JSON objects.
I'm not sure exactly what you're looking for, but there are several ways to handle it:
$.items.[*].a
Will return all values of a. This might be okay if everything has an a:
[1, 2]
If you want to get something with a specific value for a, you can use the following syntax:
$.items[?(#.a == 2)]
This returns:
[
{
"a": 2,
"b": {
"c": 2
}
}
]
See the JSONPath Github page for other examples.

Optimised Approach to parse n JSON object parallel and form aggregated json

As part of the effective implementation of parse the multiple JSON's and aggregate the resultant JSON as final out.
Let suppose :
Json1 :
[
{
"id":"abc",
"name" : "json"
},
... having 10k json objects
]
Json2:
[
{
"id":"abc",
"language" : "java"
},
... having 10k json objects
]
Json3:
[
{
"id":"abc",
"subject" : "solving"
},
... having 10k json objects
]
from the 3 jsons, requirements is
1. Optimised ways the search for the attribute "id" in 3 jsons and if match the map those json objects to final json object .
Approach followed
I tried in the following way
Iterate over the first JSON array object and find the one attribute "id" and iterate over remaining JSON's and look the matching "id" and corresponding JSON object merging and forming final objects
In this process,
Taking O(n^3) time for search the find the matching records
more ever n > 10k in my case
What will be the best approach to proceed
Assuming you already know all the possible JSON fields and id is a unique attribute,
create a java object to reflect all the fields.
class MyObject{
String id;
String name;
String language;
String subject;
}
Then create a list of key value pair, with id as the key. And whenever you find an id, if it is present in the list of key-value pair then modify the corresponding object. Otherwise create a new object and add it as a new key-value pair to the list. With this you'll be traversing each JSON only once but it might take a lot of auxiliary space.

Read a particular object on the basis of value in java [duplicate]

This question already has answers here:
Query a JSONObject in java
(6 answers)
Closed 4 years ago.
I have some json data
{
"attributesMappings": [
{
"domainType": "WI",
"attribute": [
{
"staticAttributes": [
{
"attributeName": "test",
"attributeValue": "test",
"required": true
}
]
}
]
},
{
"domainType": "PI",
"attribute": null
}
]
}
I can read the object using
JSONArray vendorData = mainObj.getJSONArray("attributesMappings");
Suppose I want to get only the object where where domain type ="WI", I know it can be done using
JSONObject obj = vendorData.getJSONObject(0);
And then I can perform the manipulations, suppose I dont know at what index "WI" will be stored, is there a way of getting the data. I know we can iterate over the array items and match for domainType.
Can we do it in a way whereby using "WI" in the getJSONObject or something of that sort I can get the complete object.
JSONObject domainType = attributeMappings.getJSONObject("WI");
AFAIK, there is no more efficient way of searching a JSON object tree than iterating it. But the cost of searching will actually be small compared with the cost of parsing the object tree.
You could potentially do better than the "parse to JSONObject" using a stream-based parser, and coding your parse event handlers to look for the information you are trying to extract. If the information you are looking for is near the beginning of the JSON serialization, you could save time by abandoning the parse as soon as you get a search "hit".
If you only doing one search of the JSON, that is the end of the story.
If you are going to search the same JSON repeatedly, then the way to get better performance is:
Parse the JSON tree, or map it to a POJO tree
Construct a separate index data structure for the in-memory tree.
Use the index to speed up searches.
So, in your example you might build an index for all attribute mappings based on the domainType field.
Alternatively, extract just the information you want into a data structure that is designed for your needs.
There are libraries around that do the equivalent of XQuery and XPath for JSON. This approach is definitely more convenient than writing a bunch of iteration code; e.g. (from #cricket_007's comment):
The JSONPath query [for your example] would be $.attributesMappings[?(#.domainType == "WI")]
For more information: Query a JSONObject in java
However, I would be hesitant to use "JSON query" libraries if you are looking for a more efficient solution.

What kind of json starts with length

I am getting a json array from server like below
69[0,{"dabcdefghij":{},"abcdefg":"20","abcdefghijklmn":"10, AB-11111"}]
I know the data inside [ ] is json. But the server is also sending the length of the json.
Right now i am finding the first occurence of [ and parsing the json.
Is it the right way? I am using gson. Is there a better method to parse this?
69[0,{"dabcdefghij":{},"abcdefg":"20","abcdefghijklmn":"10, AB-11111"}] is not valid JSON according to json.org as it's not object nor an array.
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is
realized as an object, record, struct, dictionary, hash table, keyed
list, or associative array.
An ordered list of values. In most languages, this is realized as an
array, vector, list, or sequence.

Categories