How do I parse Json data with Gson when not everything is labelled

How do I parse Json data with Gson when not everything is labelled



I have happily been using Google Gson to parse extract some JSON metadata of the form


Gson



"lowlevel":
"average_loudness": 0.570070445538
,
"rhythm":
"beats_count": 502,
"bpm": 128.347702026
,
"tonal":
"chords_changes_rate": 0.0534749031067
"tuning_diatonic_strength": 0.431238204241,
"tuning_equal_tempered_deviation": 0.164615109563,
"tuning_frequency": 434.193115234,
"tuning_nontempered_energy_ratio": 0.847496032715




Using this


public class AcousticBrainzLowlevelWrapper

private AcousticBrainzLowLevelRhythm rhythm;
private AcousticBrainzLowLevelTonal tonal;

public AcousticBrainzLowLevelRhythm getRhythm()

return rhythm;


public void setRhythm(AcousticBrainzLowLevelRhythm rhythm)

this.rhythm = rhythm;


public AcousticBrainzLowLevelTonal getTonal()

return tonal;


public void setTonal(AcousticBrainzLowLevelTonal tonal)

this.tonal = tonal;




and


AcousticBrainzLowlevelWrapper low = gson.fromJson(result, AcousticBrainzLowlevelWrapper.class) ;



(Full JSON can be seen here)



but now the API has been extended to allow multiple lookups such as this url



which now returns


{
"96685213-a25c-4678-9a13-abd9ec81cf35": {
"0":
"lowlevel":
"average_loudness": 0.570070445538
,
"rhythm":
"beats_count": 502,
"bpm": 128.347702026
,
"tonal":
"chords_changes_rate": 0.0534749031067
"tuning_diatonic_strength": 0.431238204241,
"tuning_equal_tempered_deviation": 0.164615109563,
"tuning_frequency": 434.193115234,
"tuning_nontempered_energy_ratio": 0.847496032715


.....
"78787888-a25c-4678-9a13-abd9ec81cf35": {
"0": {
"lowlevel": {
......
..



The difference being that the json doesn't define what "96685213-a25c-4678-9a13-abd9ec81cf35" and "78787888-a25c-4678-9a13-abd9ec81cf35" are, or what "0" is.



So I know what they represent (MusicBrainzRecording and offset) but I cannot create a class like AcousticBrainzLowlevelWrapper to represent this, so how do I parse this new api.


AcousticBrainzLowlevelWrapper



Update
I tried creating


public class AcousticBrainzLowLevelList

private Map<String, AcousticBrainzLowlevelWrapper> data = new HashMap<>();

public Map<String, AcousticBrainzLowlevelWrapper> getData()

return data;


public void setData(Map<String, AcousticBrainzLowlevelWrapper> data)

this.data = data;




and then calling


AcousticBrainzLowLevelList lowMap = gson.fromJson(result, AcousticBrainzLowLevelList.class) ;



but nothing get added to the map. Unsuprisingly because data I dont' see how can i give a name since there is no consistent name at the top level.


data





I think this is a Map.
– Mickaël B
Aug 21 at 12:52


Map





Right, so i guess I need to create a wrapper class for AcousticBrainzLowlevelWrapper that contains map of them, not clear on what it should look like.
– Paul Taylor
Aug 21 at 12:55





I think you should have a key String map of your current AcousticBrainzLowlevelWrapper like this Map<String, AcousticBrainzLowlevelWrapper>
– Mickaël B
Aug 21 at 12:59



String


AcousticBrainzLowlevelWrapper


Map<String, AcousticBrainzLowlevelWrapper>





Isnt it more complex than that because at top level there each contains "0" (Xml is so much easier to understand !)
– Paul Taylor
Aug 21 at 13:01




2 Answers
2



It seems to me that your input JSON could be parsed to produce a Java class of type Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>> :


Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>>


Type type = new TypeToken<Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>>>().getType();
Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>> result = gson.fromJson(json, type);





HI, I dont seem able to access com.google.gson.reflect.TypeToken says has protected access ?
– Paul Taylor
Aug 21 at 13:35





You beat me to it, I just finished testing the same solution :)
– Bentaye
Aug 21 at 13:37





@PaulTaylor he forgot , try like this: Type type = new TypeToken<Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>>>().getType();
– Bentaye
Aug 21 at 13:41



Type type = new TypeToken<Map<String,Map<Integer,AcousticBrainzLowlevelWrapper>>>().getType();





@Bentaye you're right. Just corrected.
– Maurice Perry
Aug 21 at 13:42






Brilliant, that works. My only question is does the outer map it use a sortedmap, if not can it be so is same order as the json
– Paul Taylor
Aug 21 at 13:59



As I wrote it, I might as well post it:
Similar to Maurice's answer


import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.Map;

public class Main

private final static String jsonSingle =
" "attribute1": "value1", "attribute2": "value2" ";

private final static String jsonMultiple =
"n" +
" "96685213-a25c-4678-9a13-abd9ec81cf35": n" +
" "0": "attribute1": "value1", "attribute2": "value2" n" +
" ,n" +
" "78787888-a25c-4678-9a13-abd9ec81cf35": n" +
" "0": "attribute1": "value3", "attribute2": "value4" n" +
"";

public static void main(String args)
MyBean bean = new Gson().fromJson(jsonSingle, MyBean.class);
System.out.println(bean);

Type type = new TypeToken<Map<String, Map<String, MyBean>>>().getType();
Map<String, String> myMap = new Gson().fromJson(jsonMultiple, type);
System.out.println(myMap);




MyBean class:


class MyBean
String attribute1;
String attribute2;

public String getAttribute1()
return attribute1;


public void setAttribute1(String attribute1)
this.attribute1 = attribute1;


public String getAttribute2()
return attribute2;


public void setAttribute2(String attribute2)
this.attribute2 = attribute2;


@Override
public String toString()
return "MyBean: <attribute1: " + attribute1 + "



Outputs:


MyBean: <attribute1: value1 | attribute2: value2>



and


96685213-a25c-4678-9a13-abd9ec81cf35=0=MyBean: <attribute1: value1 , 78787888-a25c-4678-9a13-abd9ec81cf35=0=MyBean: <attribute1: value3





Thanks for taking the time to do this, but the other answer is more closely aligned to my data.
– Paul Taylor
Aug 21 at 14:04






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

Node.js puppeteer - Use values from array in a loop to cycle through pages