3

I am struggling with json-parsing in java.
Is there a possibility to generate a representation of a random, not standardised json file in java? I tried to use gson but I didn't really understood if and how that might be possible.

So the jsonFile could look like this:

{ 
 "id":16875,
 "position":[1,2,5,7],
 "metadata":{
     "color":"blue",
     "id": "84779jh",
     "more":{ "some":"randomdata","absolutly":"noStructure"}
}

any key-value pairs are possible and the json file can be nested as much and as deep as it wants to. I need to get something like a java object out of it to be able to merge it with another json file. I just need the metadata part, the rest can be ignored.

So anybody any ideas how I could make that work? I would appreciate any helps :)

the json above merged with (this is the parent node, so we keep his id and position and just merge the metadata)

  { 
   "id":16zut,
   "position":[1,2,5,7],
   "metadata":{
     "color":"green",
     "id": "84ergfujh",
     "more":{ 
        "some":"randomdata",
        "even":"more",
        "absolutly":"noStructure"
     },
     "tags":[1,2,3,4,6,8,f7,h,j,f]
   }

would be:

  { 
   "id":16zut,
   "position":[1,2,5,7],
    "metadata":{
    "color":["blue", "green"],
    "id": ["84779jh","84ergfujh]",
    "more":{ "some":"randomdata","absolutly":"noStructure","even":"more"}
    "tags":[1,2,3,4,6,8,f7,h,j,f]
  }

Thanks in advance and have a nice day.

Skyler Tao
  • 33
  • 1
  • 8
malle
  • 334
  • 4
  • 17
  • Using Gson or Jackson you can unmarshall your Json into a `Map` which will represent the entire structure. I'm not really sure what the question is asking beyond that. – Boris the Spider Mar 17 '14 at 16:44
  • and if it is nested there would be just another map in the map right? Could you give a short code snippet? – malle Mar 17 '14 at 16:49
  • [Here's the first result on Google](http://www.mkyong.com/java/how-to-convert-java-map-to-from-json-jackson/). Google is your friend. – Boris the Spider Mar 17 '14 at 16:53
  • What do you mean by merging exactly? – fge Mar 17 '14 at 17:03
  • If the structure is really that arbitrary you should get the result as a `JsonNode` (Jackson) or `JsonElement` (Gson). Note though that navigating JSON is _much_ easier with Jackson. – fge Mar 17 '14 at 17:09
  • I merge metadata from a 3d szene hierarchy, to allow a user to navigate by searching for keywords, values or other metadata. So i get those informations as json files and i merch bottom up those in the parent directories. – malle Mar 17 '14 at 17:11
  • OK, but how? Can you give an example of two JSON texts and the expected merged JSON text? – fge Mar 17 '14 at 17:12
  • well thank you so much i think i finally understood it :) i will try it tomorrow morning and reply the solution (or not solution :D) – malle Mar 17 '14 at 17:23

2 Answers2

5

After seeing the json you posted i think you are trying to merger two json of with same id but different metadata id. Since the json work on the key value. you can't have two value for the same key such as in this value

"color":"blue", "green",
"id": "84779jh","84ergfujh"

unless you take color as a array. After seeing ur json you create map on the basis of the metadata id and you can add those metadata map to single metadata map

        import java.io.File;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.type.TypeReference;
    import com.google.common.collect.ImmutableMap;
    public class JsonFileMapExample {
        public static void main(String[] args) {
            try {
                ObjectMapper mapper = new ObjectMapper();
                // read JSON from a file
                Map<String, Object> map_json1 = mapper.readValue(new File(
                        "F:/Work/DB/work/workspace/restclient/src/json1.json"),
                        new TypeReference<Map<String, Object>>() {
                        });
                Map<String, Object> map_json2 = mapper.readValue(new File("F:/Work/DB/work/workspace/restclient/src/json2.json"),new TypeReference<Map<String, Object>>() { });
                System.out.println(map_json1);
                System.out.println(map_json2);
                Map<String, Object> map2 = (Map<String, Object>) map_json1.get("metadata");         
                Map<String, Object> map_json3 = new HashMap<String, Object>();          
                map_json3 = mergeMyTwoMaps((Map<String, Object>) map_json1.get("metadata"),(Map<String, Object>) map_json2.get("metadata"));            
                System.out.println(map_json3);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        static Map<String, Object> mergeMyTwoMaps(Map<String, Object> map1, Map<String, Object> map2) {
              return ImmutableMap.<String, Object>builder()
                  .putAll(map1)
                  .putAll(map2)
                  .build();
            }

        }

Output:

json1=  {id=16875, position=[1, 2, 5, 7], metadata={id=84779jh, color=blue, more={some=randomdata, absolutly=noStructure}}} 
json2={id=16875, position=[1, 2, 5, 7], metadata={id=84779jhdf, color=green, more={some=dsfasdf, absolutly=afdsadsf}}}
json3_aftermerged={id=16875, position=[1, 2, 5, 7], metadata={id=84779jh, color=blue, more={some=randomdata, absolutly=noStructure}},{id=16875, position=[1, 2, 5, 7], metadata={id=84779jhdf, color=green, more={some=dsfasdf, absolutly=afdsadsf}}}

Note for using this u need to have jar file from http://code.google.com/p/guava-libraries/

ramesh027
  • 796
  • 1
  • 10
  • 27
  • I guess my example wasn't the best. English isn't my mother tongue and json isn't either ^^ but back to the case: I want to merge just the metaData part of the Json file, the rest doesn't matter for my search, the part above is just from the parent jsonfile, we need to keep it but not to do something with it – malle Mar 18 '14 at 09:08
  • I am assuming that u want to store only different metadata in single json file. if that is the case than u can extract it from the different json and place it in single json as explain above. As json work on key value pair we cant have two value for single unless it is an array `json3_aftermerged={id=16875, position=[1, 2, 5, 7], metadata={id=84779jh, color=blue, more={some=randomdata, absolutly=noStructure}},{id=16875, position=[1, 2, 5, 7], metadata={id=84779jhdf, color=green, more={some=dsfasdf, absolutly=afdsadsf}}}` – ramesh027 Mar 18 '14 at 10:29
1

I got my problem solved and i am grateful thank you guys helped me with it. So let me share:

I read the 2 jsons both as a tree (i am using Jackson):

   ObjectMapper mapper = new ObjectMapper();
   JsonNode parent = mapper.readTree(new File(path)); 
   JsonNode child= mapper.readTree(new File(path)); 

And the merge logic isn't done yet but the basic concept is:

 Iterator<String> pIt = parent.fieldNames();
    while(pIt.hasNext())
    {
        String tempkey = pIt.next();

        if(child.path(tempkey) != null)
        {
            merged.put(tempkey,child.path(tempkey));

        }
        else{
                merged.put(tempkey,parent.path(tempkey) );
        }

    }

    try {
        String jsonString = mapper.writeValueAsString(merged);
        System.out.println(jsonString);
    } catch (JsonProcessingException e) {...}

If you think it is a dumb solution, i am open for other ideas...
But i think it might work for my needs.

greetings and thanks :)

malle
  • 334
  • 4
  • 17
  • 1
    if anyone else need help with that http://wiki.fasterxml.com/JacksonTreeModel is quite enlightend – malle Mar 19 '14 at 10:06