'Get key values of nested json objects

I want to get the values of the keys of the next json file using org.json library:

{
    "1": {
        "subject1": "MIS",
        "subject2": "DBMS",
        "subject3": "UML"
    },
    "2": {
        "subject1": "ART",
        "subject2": "MATH",
        "subject3": "MUSIC"
    },
    "3": {
        "subject1": "HISTORY",
        "subject2": "CHEMISTY",
        "subject3": "BIOLOGY"
    }
}

This is what I have tried:

package com.company;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.FileReader;

public class Main {
    public static void main(String[] args) {
        String json = "{\"1\": {\"subject1\": \"MIS\",\"subject2\": \"DBMS\",\"subject3\": \"UML\"},\"2\": {\"subject1\": \"ART\",\"subject2\": \"MATH\",\"subject3\": \"MUSIC\"},\"3\": {\"subject1\": \"HISTORY\",\"subject2\": \"CHEMISTY\",\"subject3\": \"BIOLOGY\"}}";

        try{
            JSONObject root = new JSONObject(json);
            for (int i = 0; i < root.length(); i++) {
                JSONArray subjects = root.getJSONArray(String.valueOf(i+1));

                for (int j = 0; j < subjects.length(); j++) {
                    JSONObject number = subjects.getJSONObject(j);
                    String s1 = number.getString("subject1");
                    String s2 = number.getString("subject2");
                    String s3 = number.getString("subject3");
                    System.out.println(s1+", "+ s2+", "+s3);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

With JSONArray subjects = root.getJSONArray(String.valueOf(i+1)); I thought I was getting:

JSONArray subjects = root.getJSONArray("1");
JSONArray subjects = root.getJSONArray("2");
...

But that doesn´t work for me. I just get in console the next:

org.json.JSONException: JSONObject["1"] is not a JSONArray.
    at org.json.JSONObject.wrongValueFormatException(JSONObject.java:2694)
    at org.json.JSONObject.getJSONArray(JSONObject.java:777)
    at com.company.Main.main(Main.java:18)

And I would like to get:

MIS, DBMS, UML
ART, MATH, MUSIC
HISTORI, CHEMISTRY, BIOLOGY

Can you tell me what I am doing wrong? Should I use other library? Thanks for your help.



Solution 1:[1]

You got it all correct until this point

JSONArray subjects = root.getJSONArray(String.valueOf(i+1));

you have to get JSONObject not JSONArray since you don't have an array. Your second mistake is this loop

for (int j = 0; j < subjects.length(); j++) {}

since you're already getting the object manually you don't have to loop.

Final Code

    String json = "{\"1\": {\"subject1\": \"MIS\",\"subject2\": \"DBMS\",\"subject3\": \"UML\"},\"2\": {\"subject1\": \"ART\",\"subject2\": \"MATH\",\"subject3\": \"MUSIC\"},\"3\": {\"subject1\": \"HISTORY\",\"subject2\": \"CHEMISTY\",\"subject3\": \"BIOLOGY\"}}";

    try {
        JSONObject root = new JSONObject(json);
        for (int i = 0; i < root.length(); i++) {
            JSONObject number = root.getJSONObject(String.valueOf(i + 1));
            String s1 = number.getString("subject1");
            String s2 = number.getString("subject2");
            String s3 = number.getString("subject3");
            System.out.println(s1 + ", " + s2 + ", " + s3);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

OUTPUT

MIS, DBMS, UML
ART, MATH, MUSIC
HISTORY, CHEMISTY, BIOLOGY

Solution 2:[2]

Subjects is not an array. Arrays in JSON would be enclosed in [ and ].To get the subjects, you would need follow below approach.

try{
     JSONObject root = new JSONObject(json);
     for (int i = 0; i < 3; i++) {
        JSONObject Obj = root.getJSONObject(String.valueOf(i+1));
        String s1 = Obj.getString("subject1");
        String s2 = Obj.getString("subject2");
        String s3 = Obj.getString("subject3");
        System.out.println(s1+", "+ s2+", "+s3);
      }
  }catch(Exception e){
            e.printStackTrace();
  }

Above JSON when modified like below, would then become an json array [{"subject1": "MIS","subject2": "DBMS","subject3": "UML"},{"subject1": "ART","subject2": "MATH","subject3": "MUSIC"},{"subject1": "HISTORY","subject2": "CHEMISTY","subject3": "BIOLOGY"}]

And then values can be extracted as mentioned below,

try{
    JSONArray root = new JSONArray(json);

    for (int i = 0; i < root.length(); i++) {
       JSONObject Obj = root.getJSONObject(i);
       String s1 = Obj.getString("subject1");
       String s2 = Obj.getString("subject2");
       String s3 = Obj.getString("subject3");
       System.out.println(s1+", "+ s2+", "+s3);
   }
}catch(Exception e){
  e.printStackTrace();
}

Solution 3:[3]

The code will be lengthy to get data from a file of nested JSON format in Java.

You can use SPL, the open-source Java package, to get this done. It is simple and only one line of code is sufficient:

A
1 =json(file("org.json").read()).array()

SPL offers JDBC driver to be invoked by Java. Just store the above SPL script as getjsonarray.splx and invoke it in Java as you call a stored procedure:

…
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
st = con.prepareCall("call getjsonarray()");
st.execute();
…

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Saif Ahmad
Solution 2
Solution 3