Parsing nested json array

I am having some trouble getting the values that I want from a json-file. I am using simple-json. It looks like this:

 [
  {
    "BUTT LIFT (BRIDGE)": [
      {
        "Main Muscle Worked": "Glutes",
        "Sport": "No",
        "Force": "Push",
        "Level": "Beginner",
        "mucle_heatmap": "http://assets.bodybuilding.com/images/trackers/exercise/heatmap/14.gif",
        "female_image_end": "http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Female/l/99_2.jpg",
        "female_image_start": "http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Female/l/99_1.jpg",
        "guide": [
          "Lie flat on the floor on your back with the hands by your side and your knees bent.   Your feet should be placed around shoulder width.  This will be your starting position.",
          "Pushing mainly with your heels, lift your hips off the floor while keeping your back straight.  Breathe out as you perform this part of the motion and hold at the top for a second.",
          "Slowly go back to the starting position as you breathe in."
        ],
        "male_image_start": "http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Male/l/99_1.jpg",
        "Equipment": "Body Only",
        "link": "http://www.bodybuilding.com/exercises/detail/view/name/butt-lift-bridge",
        "male_image_end": "http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Male/l/99_2.jpg",
        "Other Muscles": "Hamstrings",
        "Type": "Strength",
        "Mechanics Type": "Isolation"
      }
    ]
  },

The file is large and contains around 800 exercises. What I want is to map the Strings, such as "Force", "Level", but I am unsure of how I am going to access it.

This is my code so far

public void parse() {
    JSONParser parser = new JSONParser();
    try {
        Object obj = parser.parse(new FileReader(filePath));
        JSONArray exerciseList = (JSONArray) obj;

        for (int i = 0; i < exerciseList.size(); i++) {
            JSONObject jsonObj = (JSONObject) exerciseList.get(i);

        }

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ParseException e) {
        e.printStackTrace();
    }
}

This results in getting the whole JSON-file.

2 answers

  • answered 2018-03-22 13:00 OldCurmudgeon

    It is not difficult to walk the JSON recursively using json-simple. Here I only watch for String and Long fields but it is obvious how to add more.

    public class WalkJSON {
        private static final String PATH_SEPARATOR = "/";
    
        /**
         * Offers the opportunity to examine fields in the JSON.
         */
        public static class FieldVisitor {
            void visit(String path, String value){};
            void visit(String path, Long value){};
        }
    
        /**
         * Walks the JSON structure calling the visitor for every String field in the structure.
         */
        public static void walk(String jsonString, FieldVisitor visitor) throws ParseException {
            walk(new JSONParser().parse(jsonString), "", visitor);
        }
    
        /**
         * Discerns which type of object it is and dispatches to the correct method.
         */
        private static void walk(Object json, String path, FieldVisitor visitor) {
            if (json instanceof JSONObject) {
                walk((JSONObject) json, path, visitor);
            } else if (json instanceof JSONArray) {
                walk((JSONArray) json, path, visitor);
            } else if (json instanceof String) {
                visitor.visit(path, (String) json);
            } else if (json instanceof Long) {
                visitor.visit(path, (Long) json);
            } else {
                System.out.println("Unknown type "+json.getClass());
            }
        }
    
        /**
         * Walks all keys of a JSONObject.
         */
        private static void walk(JSONObject json, String path, FieldVisitor visitor) {
            for (Object o : json.entrySet()) {
                Map.Entry<String, Object> e = (Map.Entry<String, Object>) o;
                // Visit every entry.
                walk(e.getValue(), path + PATH_SEPARATOR + e.getKey(), visitor);
            }
        }
    
        /**
         * Walks all entries in a JSON array.
         */
        private static void walk(JSONArray json, String path, FieldVisitor visitor) {
            for (int i = 0; i < json.size(); i++) {
                // Visit every entry.
                walk(json.get(i), path + PATH_SEPARATOR + i, visitor);
            }
        }
    }
    

    You can then write your own visitor to capture specific fields.

        WalkJSON.walk(json, new WalkJSON.FieldVisitor() {
            @Override
            public void visit(String path, String value) {
                if(path.contains("/guide/")) {
                    System.out.println(value);
                }
            }
        });
    

    All you now need to do is work out how to choose what fields you are looking for with a regex or something.

  • answered 2018-03-22 13:00 Mithun Debnath

    Here I am using org.json. By considering your input JSON and the position of comma , you have given I am assuming "BUTT LIFT (BRIDGE)" will always have one element. If it has more element than 1,we will have to write another inner loop for BUTT LIFT (BRIDGE).

    package org.home.example;
    
    import java.util.HashMap;
    
    import org.json.JSONArray;
    
    import org.json.JSONObject;
    
    public class Test {
    
    public static void main(String[] args) {
        //input arry with with two elements. It can have more elements
        String StringJson="[{\"BUTT LIFT (BRIDGE)\":[{\"Main Muscle Worked\":\"Glutes\",\"Sport\":\"No\",\"Force\":\"Push\",\"Level\":\"Beginner\",\"mucle_heatmap\":\"http://assets.bodybuilding.com/images/trackers/exercise/heatmap/14.gif\",\"female_image_end\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Female/l/99_2.jpg\",\"female_image_start\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Female/l/99_1.jpg\",\"guide\":[\"Lie flat on the floor on your back with the hands by your side and your knees bent.   Your feet should be placed around shoulder width.  This will be your starting position.\",\"Pushing mainly with your heels, lift your hips off the floor while keeping your back straight.  Breathe out as you perform this part of the motion and hold at the top for a second.\",\"Slowly go back to the starting position as you breathe in.\"],\"male_image_start\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Male/l/99_1.jpg\",\"Equipment\":\"Body Only\",\"link\":\"http://www.bodybuilding.com/exercises/detail/view/name/butt-lift-bridge\",\"male_image_end\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Male/l/99_2.jpg\",\"Other Muscles\":\"Hamstrings\",\"Type\":\"Strength\",\"Mechanics Type\":\"Isolation\"}]},{\"BUTT LIFT (BRIDGE)\":[{\"Main Muscle Worked\":\"Glutes\",\"Sport\":\"No\",\"Force\":\"Push1\",\"Level\":\"Beginner1\",\"mucle_heatmap\":\"http://assets.bodybuilding.com/images/trackers/exercise/heatmap/14.gif\",\"female_image_end\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Female/l/99_2.jpg\",\"female_image_start\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Female/l/99_1.jpg\",\"guide\":[\"Lie flat on the floor on your back with the hands by your side and your knees bent.   Your feet should be placed around shoulder width.  This will be your starting position.\",\"Pushing mainly with your heels, lift your hips off the floor while keeping your back straight.  Breathe out as you perform this part of the motion and hold at the top for a second.\",\"Slowly go back to the starting position as you breathe in.\"],\"male_image_start\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Male/l/99_1.jpg\",\"Equipment\":\"Body Only\",\"link\":\"http://www.bodybuilding.com/exercises/detail/view/name/butt-lift-bridge\",\"male_image_end\":\"http://www.bodybuilding.com/exercises/exerciseImages/sequences/99/Male/l/99_2.jpg\",\"Other Muscles\":\"Hamstrings\",\"Type\":\"Strength\",\"Mechanics Type\":\"Isolation\"}]}]";
        JSONArray object=new JSONArray(StringJson);
        HashMap<Integer,String> Force=new HashMap<Integer,String>();
        HashMap<Integer,String> Level=new HashMap<Integer,String>();
        //iterate the array
        for(int i=0;i<object.length();i++){
            JSONObject parts=object.getJSONObject(i).getJSONArray("BUTT LIFT (BRIDGE)").getJSONObject(0);
            Force.put(i, parts.getString("Force"));
            Level.put(i,parts.getString("Level"));
        }
    
        System.out.println("Force map");
        for (HashMap.Entry<Integer, String> entry : Force.entrySet())
        {
            System.out.println(entry.getKey() + "/" + entry.getValue());
        }
    
        System.out.println("Level map");
        for (HashMap.Entry<Integer, String> entry : Level.entrySet())
        {
            System.out.println(entry.getKey() + "/" + entry.getValue());
        }
    }
    
    }