Is it possible to change the name of a Json property without serialization with Gson? For example, given this Json
{
"1": {
...
},
"2": {
...
}
}
could I change the "1" to a "3" without removing its contents. I know that the addProperty method adds a new property, or overwrites an existing property with a new value, but I want to change the name of a property without affecting its value. Also, pasting the existing value as the second argument of addProperty will not suffice.
EDIT: To add more context, I will explain the bigger picture. I have a JSON string that is a couple thousand lines long. I'm writing a program leveraging Gson in order to change the values in that JSON string. I am at a point where I not only want to change the values of properties, but the names of the properties themselves. I have done everything so far without serialization.
Here is a snippet of the Java I wrote:
String file = "\\temp.json";
FileReader reader = new FileReader(file);
JsonStreamParser parser = new JsonStreamParser(reader);
// Parse entire JSON
JsonElement element = parser.next();
// Get root element
JsonObject sites = element.getAsJsonObject();
// Get first child element
JsonObject site1 = sites.getAsJsonObject("1");
JsonObject clust1 = site1.getAsJsonObject("CLUST");
for(int i = 1; i < 12; i++) {
// "Dynamic" variable
String num = Integer.toString(i);
// Get property whose name is a number, has siblings
JsonObject one = custCluster1.getAsJsonObject(num);
one.getAsJsonObject().addProperty("name", "cluster" + i);
JsonObject subOne = one.getAsJsonObject("SUB");
subOne.getAsJsonObject().addProperty("name", "aName" + i);
for(int n = 1; n < 1002; n++) {
// "Dynamic" variable
String inst = Integer.toString(n);
// Get property whose name is a number, has siblings
JsonObject subSub = subOne.getAsJsonObject(inst);
// If the property doesn't exist, then don't execute
if(subSub != null) {
JsonArray subSubArray = subSub.getAsJsonArray("SUBSUB");
subSub.getAsJsonObject().remove("name");
int m = 0;
while(m < subSubArray.size()) {
subSubArray.get(m).getAsJsonObject().remove("SR");
subSubArray.get(m).getAsJsonObject().remove("FI");
subSubArray.get(m).getAsJsonObject().remove("IND");
subSubArray.get(m).getAsJsonObject().addProperty("ST", "1");
subSubArray.get(m).getAsJsonObject().addProperty("ID", "2");
subSubArray.get(m).getAsJsonObject().addProperty("DESCR", "hi");
m++;
}
m = 0;
}
}
}
Thanks to #mmcrae for helping and suggesting this method.
Since I'm already saving the (key, value) pairs in variables, you can remove the property whose name you want to change from the parent, and then add it back with a new name and the content that was already saved.
Like this:
JsonObject sites = element.getAsJsonObject();
JsonObject site1 = sites.getAsJsonObject("1");
JsonObject clust1 = site1.getAsJsonObject("CLUST");
site1.remove("CLUST");
site1.add("NEWCLUST", clust1);
Related
I need to read a JSON file with following form:
{
"Data":[{
"foo":"22",
"bar":"33",
"array":[
{
"1foo":"22",
"1bar":"33"
},
{
"2foo":"22",
"2bar":"33",
}
],
"anotherData":{
"foofoo":"22",
"barbar":"33"
},
"some more data":"11",
"some more data":"11"
},
{and the cycle here starts again from -->
"foo":"22",
"bar":"33",
"array":[
My question stands : How do I access individual elements given it's sometimes JSONObject and sometimes JSONArray. I tried using org.json library but I'm failing to access anything after this line -> "array":[. I tried various combinations of JSONObject and JSONArray up to no avail.
My latest code looked something like this:
List<Data> data= new ArrayList<>();
String rawJson = getJsonAsString();
JSONObject outer = new JSONObject(rawJson);
JSONArray jArr= outer.getJSONArray("Data");
JSONObject inner= outer.getJSONObject("array");
for(int i =0; i<jArr.length(); i++){
JSONObject jsonEvent = jArr.getJSONObject(i);
String foo = jsonEvent.getString("foo"); <-- this works,
String 1foo = jsonEvent.getString("1foo"); <-- but this doesn't and i cant access it
I tried dozens of different solutions(tried myself and tried to find something here as well, but every case with those nested arrays is different and I can't add those solutions together to get answer for my case)
You can increase your readability if you beautify your raw JSON string:
{
"Data":[
{
"foo":"22",
"bar":"33",
"array":[
{
"1foo":"22",
"1bar":"33"
},
{
"2foo":"22",
"2bar":"33"
}
],
"anotherData":{
"foofoo":"22",
"barbar":"33"
},
"some more data":"11",
"some more data":"11"
},
{ and the cycle here starts again from -->
"foo":"22",
"bar":"33",
"array":[
...
],
...
}
]
}
So, stick to the following code:
JSONArray jArr = outer.getJSONArray("Data");
jArr is now filled with array of your Object.
And to loop through your Object array, you can use a for-loop which you have done it correctly.
for (int i = 0; i < jArr.length(); i++) {
// The below gets your Object
JSONObject jsonEvent = jArr.getJSONObject(i);
}
And now each jsonEvent contains your Object, which you can access the Object by their type.
For example, if you would like to access foo, you can use:
String foo = jsonEvent.getString("foo"); // foo = "22"
String bar = jsonEvent.getString("bar"); // bar = "33"
// Note that your array is another Array, you need to get it as JSONArray first
JSONArray arrayJson = jsonEvent.getJSONArray("array");
And as 1foo is in the first Object for your array, you need to access it like this:
JSONObject firstObjectInArray = arrayJson.getJSONObject(0);
String target = firstObjectInArray.getString("1foo"); // target = "22"
And to access foofoo, as it is an attribute of the JSON Object anotherData, so you should obtain anotherData as JSONObject first, and then you can access foofoo:
JSONObject anotherDataObject = jsonEvent.getJSONObject("anotherData");
String foofoo = anotherDataObject.getString("foofoo"); // foofoo = "22"
So the full code within your for-loop should look like this:
for (int i = 0; i < jArr.length(); i++) {
// The below gets your Object
JSONObject jsonEvent = jArr.getJSONObject(i);
String foo = jsonEvent.getString("foo");
JSONArray arrayJson = jsonEvent.getJSONArray("array");
String target = arrayJson.getJSONObject(0).getString("1foo");
// Add to get foofoo
JSONObject anotherDataObject = jsonEvent.getJSONObject("anotherData");
String foofoo = anotherDataObject.getString("foofoo");
}
This is my JSON string,
{
"listmain":{
"16":[{"brandid":"186"},{"brandid":"146"},{"brandid":"15"}],
"17":[{"brandid":"1"}],
"18":[{"brandid":"12"},{"brandid":"186"}],
}
}
I need to get values in "16","17","18" tag and add values and ids("16","17","18") to two ArrayList.
What i meant is,
when we take "16", the following process should happen,
List<String> lsubid = new ArrayList<String>();
List<String> lbrandid = new ArrayList<String>();
for(int i=0;i<number of elements in "16";i++) {
lsubid.add("16");
lbrandid.add("ith value in tag "16" ");
}
finally the values in lsubid will be---> [16,16,16]
the values in lbrandid will be---> [186,146,15]
Can anyone please help me to complete this.
Use JSONObject keys() to get the key and then iterate each key to get to the dynamic value.
You can parse the JSON like this
JSONObject responseDataObj = new JSONObject(responseData);
JSONObject listMainObj = responseDataObj.getJSONObject("listmain");
Iterator keys = listMainObj.keys();
while(keys.hasNext()) {
// loop to get the dynamic key
String currentDynamicKey = (String)keys.next();
//store key in an arraylist which is 16,17,...
// get the value of the dynamic key
JSONArray currentDynamicValue = listMainObj.getJSONArray(currentDynamicKey);
int jsonrraySize = currentDynamicValue.length();
if(jsonrraySize > 0) {
for (int i = 0; i < jsonrraySize; i++) {
JSONObject brandidObj = currentDynamicValue.getJSONObject(i);
String brandid = brandidObj.getString("brandid");
System.out.print("Brandid = " + brandid);
//store brandid in an arraylist
}
}
}
Source of this answer
How can i parse an array with direct values , twice json encoded in Java, i get the data as a string and i want to get each value from the multidimensional array.
I'm kind of a noob regarding java, i managed to pull a not so elegant solution that encounters problems when i split by "," if the text inside has "," i could do it with regex but there must be a more elegant solution than this:
content = the data fetched from the api as a string
content = content.replace("\"[[", "[");
content = content.replace("]]\"", "]");
content = content.replaceAll("\\\\","");
for (String FaData : content.split("\\],\\[")) {
for (String FaDataData : FaData.split(",")) {
FaDataData.toString();
}
}
Here you have an example of how content string actually looks like when is fetched:
"[[308576,1410880665,162506,\"Bobcat\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308576.jpg\",\"Well no\",82,3,\"\"],[308592,1410883832,9479,\"undeathkiller\",2,\"http:\\\/\\\/hugelolcdn.com\\\/i\\\/308592.gif\",\"Guess the stupidity level\",89,9,\"\"],[308574,1410879991,32277,\"rady123lol\",2,\"http:\\\/\\\/hugelolcdn.com\\\/i\\\/308574.gif\",\"force of habit\",92,3,\"\"],[308624,1410897686,149704,\"Raptide7\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308624.jpg\",\"*breathing intensifies*\",114,8,\"\"],[308648,1410911037,114669,\"Huller\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308648.jpg\",\"SPOILERS: Stannis kills Dumbledore\",133,2,\"\"],[308628,1410898654,135315,\"Mig_L\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308628.jpg\",\"So badass\",117,2,\"gold\"],[308639,1410902872,62886,\"burningowl\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308639.jpg\",\"Kid's going places yo\",125,4,\"\"],[308520,1410858123,73400,\"koppie888\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308520.jpg\",\"4chan, what a beautifull place\",99,7,\"\"],[308546,1410872801,32277,\"rady123lol\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308546.jpg\",\"( \\u0361\\u00b0 \\u035c\\u0296 \\u0361\\u00b0)\",118,17,\"\"],[308486,1410846601,176339,\"AtLeastISubmit\",1,\"http:\\\/\\\/hugelolcdn.com\\\/i460\\\/308486.jpg\",\"That 70's show called it.\",101,3,\"\"]]"
Assuming that you have your text in a String variable called everything, using the JSONSimple package, you can use the following code:
try {
// create a new JSONParser
JSONParser parser=new JSONParser();
// first JSON decoding
Object obj = parser.parse(everything);
// second JSON decoding
obj = parser.parse(obj.toString());
// cast the parsed JSON string to a new JSONArray
JSONArray array = (JSONArray)obj;
// loop through each line of the initial JSONArray
for (int i = 0; i < array.size(); i++){
// write the array values as a single line
System.out.println(i + " : " + array.get(i));
// parsing each line as a new JSONArray
JSONArray tmp = (JSONArray)parser.parse(array.get(i).toString());
for (int j = 0; j < tmp.size(); j++){ // iterate over the parsed values
System.out.println(i+"."+j+" : "+tmp.get(j));
}
}
} catch (ParseException ex) {
Logger.getLogger(Test1.class.getName()).log(Level.SEVERE, null, ex);
}
Of course, you also have to import the following classes from the JSON package :
import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
Try this
content = content.trim();
content = content.substring(0, content.length()); //gets the length of content string
content = content.replaceAll("\\/","/"); //Replaces all \/ to /
It would apply to the brackets as well.
If you're using JSON then I would suggest using a JSON library such as jackson.
ObjectMapper mapper = new ObjectMapper();
String[][] 2Darray = mapper.readValue(content, String[][].class);
But then, if you are using JSON it would be nice if the format of your data was more structured. Obviously, that depends on whether or not you have any control over the API.
I was using JSONParser to obtain results of a search, for that I followed this tutorial: http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
The thing is that, the API I am using gives the results like this:
{"response":[50036,{"aid":88131498,"owner_id":61775052,"artist":"Terror Squad","title":"Lean Back (OST Need For Speed Underground 2)","duration":249,"url":"http:\/\/cs4408.vkontakte.ru\/u59557424\/audio\/7f70f58bb9b8.mp3","lyrics_id":"3620730"},{"aid":106963458,"owner_id":-24764574,"artist":"«Dr. Dre ft Eminem, Skylar Grey (Assault Terror)","title":"I Need A Doctor (ASSAULT TERROR DUBSTEP REMIX)»","duration":240,"url":"http:\/\/cs5101.vkontakte.ru\/u79237547\/audio\/12cd12c7f8c2.mp3","lyrics_id":"10876670"}]}
My problem comes when I have to parse the first integer (here it is 50036) which is the number of results found.
I don't know how to read that integer.
This is my code:
private void instance(String artisttrack){
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
String jsonurl = new String( "https://api.vk.com/method/audio.search?access_token=ACC_TOKEN&api_id=ID&sig=SIG&v=2.0&q=" + artistname + artisttrack + "&count=5");
JSONObject json = jParser.getJSONFromUrl(jsonurl);
try {
// Getting Array of Contacts
response = json.getJSONArray(TAG_RESPONSE);
// looping through All Contacts
for(int i = 0; i < response.length(); i++){
JSONObject c = response.getJSONObject(i);
// Storing each json item in variable
//int results = Integer.parseInt(c.getString(TAG_RESULTS));
String aid = c.getString(TAG_AID);
String owner_id = c.getString(TAG_OWNER_ID);
String artist = c.getString(TAG_ARTIST);
String title = c.getString(TAG_TITLE);
String duration = c.getString(TAG_DURATION);
// Phone number is agin JSON Object
//JSONObject phone = c.getJSONObject(TAG_PHONE);
String url = c.getString(TAG_URL);
String lyrics_id = c.getString(TAG_LYRICS_ID);
Log.e("áaaaaaaaaaaaaaa", url);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
The JSONParser.java is like written in the tutorial.
And here 2 lines of the logcat error:
W/System.err(10350): org.json.JSONException: Value 50036 at 0 of type java.lang.Integer cannot be converted to JSONObject
W/System.err(10350): at org.json.JSON.typeMismatch(JSON.java:100)
Your JSON sample is a poor way to organize the results: mixing the number in with the result objects. Is the number supposed to indicate the number of objects in the array or something else?
If you can assume that this number will always be the first element, and according to this then it's supposed to work this way, you can try to read the first value of the array outside the loop:
response = json.getJSONArray(TAG_RESPONSE);
// from your example, num will be 50036:
num = response.getInt(0);
for (int i = 1; i < response.length(); i++){
JSONObject c = response.getJSONObject(i);
Note that the example in the linked documentation has this number as a string:
{"response":
["5",
{"aid":"60830458","owner_id":"6492","artist":"Noname","title":"Bosco",
"duration":"195","url":"http:\/\/cs40.vkontakte.ru\/u06492\/audio\/2ce49d2b88.mp3"},
{"aid":"59317035","owner_id":"6492","artist":"Mestre Barrao","title":"Sinhazinha",
"duration":"234","url":"http:\/\/cs510.vkontakte.ru\/u2082836\/audio\/
d100f76cb84e.mp3"}]}
But JSONArray.getInt() will parse the String as an int for you.
And notice that some of the values in the objects in your array are also numbers, you may want to read those as int also:
int aid = c.getInt(TAG_AID);
int owner_id = c.getInt(TAG_OWNER_ID);
int duration = c.getInt(TAG_DURATION);
A lot of the values you are trying to parse in are not String objects, specifically "aid", "owner_id", and "duration". Use the correct method to retrieve values. For example:
int aid = c.getInt(TAG_AID);
int owner_id = c.getInt(TAG_OWNER_ID);
String artist = c.getString(TAG_ARTIST);
String title = c.getString(TAG_TITLE);
int duration = c.getInt(TAG_DURATION);
edit: Another error that I missed is you start your array with 50036. This is not a JSONObject and cannot be parsed as so. You can add a conditional statement to check if it's array index 0 to parse the int using getInt(), and then parse as JSONObjects for the rest of the array values.
Try changing
response = json.getJSONArray(TAG_RESPONSE);
into
response = (JSONObject)json.getJSONArray(TAG_RESPONSE);
I dont have any experience with JSONObject, but works often with type mismatches.
Try putting 50036 in quotes like this "50036" .
I am a very beginner about JSON...
How can I get the value of "3037904" from the following JSON Object in Java program?
{"query":{"pages":{"3037904":{"pageid":3037904,"ns":0,"title":"Kempinski",
"categories":[{"ns":14,"title":"Category:Companies established in 1897"},{"ns":14,"title":"Category:Hotel chains"},{"ns":14,"title":"Category:Kempinski Hotels"}]}}}}
I tried to
JSONObject query = json.getJSONObject("query");
int pages = query.getInt("pages");
But it takes
"{"3037904":{"pageid":3037904,"ns":0,"title":"Kempinski",
"categories":[{"ns":14,"title":"Category:Companies established in 1897"},{"ns":14,"title":"Category:Hotel chains"},{"ns":14,"title":"Category:Kempinski Hotels"}]}}}}",
not only "3037904".
You'll need to do a little more work with your JSONObject.
In this answer I'll assume that you want to get at that pageid value.
Let's only assume the existence of pageid in the nesting - at a specific level:
// "query" is the top-level object:
JSONObject query = json.getJSONObject("query");
// "pages" is a field of "query"
JSONObject pages = query.getJSONObject("pages");
// these will hold the object with the value that you want, and that value:
JSONObject nestedObject = null;
int pageId = 0;
// these are the property names in the "pages" object:
String[] keys = pages.getNames(pages);
// iterate over the keys in the "pages" object, looks for JSONObjects:
for (int i = 0; i < keys.length; i++)
{
try
{
nestedObject = pages.getJSONObject(keys[i]);
// only consider objects with a "pageid" key, stop at the first one:
if (nestedObject.has("pageid"))
break;
}
catch (JSONException je)
{ ; }
}
if (nestedObject != null)
pageId = nestedObject.getInt("pageid");
Your JSON input seems peculiar in that the first nested object has a pages field, that contains another object. The name in plural, pages, and the nested object - which duplicates the key containing the object as a pageid key within the object - suggests that pages should be an array of multiple such objects.
Take a look at the GSON Library: http://code.google.com/p/google-gson/
Here are good examples: https://sites.google.com/site/gson/gson-user-guide#TOC-Primitives-Examples
Gson gson = new Gson();
Map map = gson.fromJson("{\"query\":{\"pages\":{\"3037904\":{\"pageid\":3037904,\"ns\":0,\"title\":\"Kempinski\", \"categories\":[{\"ns\":14,\"title\":\"Category:Companies established in 1897\"},{\"ns\":14,\"title\":\"Category:Hotel chains\"},{\"ns\":14,\"title\":\"Category:Kempinski Hotels\"}]}}}}", HashMap.class);
Map query = (Map) map.get("query");
Map pages = (Map) query.get("pages");
System.out.println(pages.keySet());
Map page = (Map) pages.get("3037904");
System.out.println(page);
System.out.println(page.get("pageid"));