1

I have a database I made in Json. I have this parsed, and have the code iterating through a Json array, which contains several Json objects. Finally, I also am iterating through the values in the Json objects. My problem is that I need to check if the value that the iterator is on, is a string or an array.

Google seems to only have things like checking if there is a number in a string, or some other variation of that question.

SO questions doesn't appear to have much for what I want. There was a case that was very similar to mine, however it is dealing with primitive data types, so my case that is dealing with string doesn't work. (Here is the link to that other case: Java how to check if a string value is a type of given Class<?> )

Here is a small portion of my database: The configuration arrays get longer as you go deeper into the database. I can not simply hold the values in a string, as "superscript" needs to be formatted as a superscript on the "term". I plan to do this later, but either way I will need to have the program figure out if it is dealing with a string or an array.

{
"Elements" : [
    {
    "name" : "Hydrogen",
    "Symbol" : "H",
    "atomicNumber" : "1",
    "electronegativity" : "2.2",
    "group" : "Hydrogen",
    "ionCharge1" : "1+",
    "ionCharge2" : "1-",
    "molarMass" : "1.01",
    "naturalState" : "Gas",
    "synthetic" : "false",
    "diatomic" : "true",
    "columnNumber" : "1",
    "row" : "1",
    "columnCode" : "IA",

    "nobleGasConfiguration" : [
        {
        "term:" : "No Noble Gas Configuration",
        "superScript" : "-"
        }
    ],
    "electronConfiguration" : [
        {
        "term" : "1s",
        "superScript" : "1"
        }
    ]
    }
}

Here is my code: The part of the code that is post to find out whether it is dealing with a string or a array is at the if statement (there is only 1 if statement)

import javax.json.Json;
import javax.json.JsonReader;
import javax.json.JsonStructure;
import javax.json.JsonObject;
import javax.json.JsonArray;
import javax.json.JsonValue;
import java.util.Iterator;
import java.util.Collection;
import java.io.FileReader;
import java.io.IOException;
import java.lang.String;

public class DataTest
{
public static void main(String[]args) throws IOException
{
    String strValue = "";
    JsonReader reader = Json.createReader(new FileReader("Elements.JSON"));
    JsonObject jsonst = reader.readObject();

    JsonArray elements = jsonst.getJsonArray("Elements"); 
    for (int i = 0; i < elements.size(); i++) 
    {
        JsonObject element = elements.getJsonObject(i); 
        Collection<String> elementValues = element.keySet(); 
        Iterator<String> elementKeys = elementValues.iterator(); 
        while(elementKeys.hasNext())
        {
            if(elementKeys.next() instanceof java.lang.String)
            {
                System.out.println(elementKeys.next());
                String elementKey = elementKeys.next();
                strValue = element.getString(elementKey); 
                System.out.println(strValue); 
            }
        }
    }

    reader.close();
}
}

I think I have the if statement is almost completed, but I have into the original problem again. elementKeys.next() gets the name for a value. For example "name", "symbol", "nobleGasConfiguration". For the actual values (like "Hydrogen" from "name" : "Hydrogen"), I've been getting that as a string with the .getString() method. However, this causes the program to crash when it tries to get a array, because .getString() is for getting strings... Not arrays.

My main issue is getting the correct value to check. My current if statement always comes up as true. This is because the values that .next() gets are indeed strings, and therefore the instanceof returns true. This the case even for the array names. Then the program goes into the if statement and crashes when .getString() tries to get an array.

if(elementKeys.next() instanceof java.lang.String)

So, my question. How do I safely get the right value (such as "Hydrogen" from "name" : "Hydrogen") for my if statement to check? (Doesn't matter if I need to use an entirely different method to check the value type, ultimately I need a means to check the value type)

What programs/versions am I using?

Notepad

Command-prompt

Java 8

javax.json-1.0.jar

Please keep the answers to java and javax.json.

Community
  • 1
  • 1
Tyler
  • 957
  • 11
  • 27
  • Typically when dealing with JSON, and especially when you are dealing with data your own or that is in your database, you know the expected structure. Why are you trying to handle this as is you don't know in advance what the JSON structure will look like. What I mean is, you know that nobleGasConfiguration and electronConfiguration are array types, do you not? In addition, don't you want to handle numuric values like molarMass as an int? – pczeus Mar 18 '16 at 16:10
  • there are no numeric values, the values are meant to be displayed. Some strings that hold numbers will have other uses that require getting the number, but the process is that it starts as a string, gets passed into a instance of a class (this not coded yet, so I just out print the values for now) then the information is used. – Tyler Mar 18 '16 at 16:16
  • as for not knowing the values, I know 2 possible values - string and array. However I need the program to check if the value is a string or array, so it doesn't try to use getString() to get an array. Which would result in a crash. I could set up a string for each value, but then I would be passing in like 13 values to an instance of a class later down the road. Having the program go through each value one by one and passing them in to the instance would be more efficient. – Tyler Mar 18 '16 at 16:18
  • So, if you have an array, for now what do you want to do? Loop over the array and print each element of the array? – pczeus Mar 18 '16 at 16:26
  • For now I want to get the value type of the information("name" : "Hydrogen", What is the value type of "Hydrogen"?) Whether this is done just before if statement, or inside the if statement condition doesn't matter. My main issue is I have elementKeys.next(), this would give "name" (from the example just above), but how would I get "Hydrogen" (where I can get either a array or a string)? – Tyler Mar 18 '16 at 16:39
  • I believe my answer will help you solve your problem. Handling the nested array elements recursively. Give it a try. – pczeus Mar 18 '16 at 18:11
  • I like to try to understand what the code is saying, so this is going to take me a little while to read, look up the methods and comprehend. – Tyler Mar 18 '16 at 18:20

1 Answers1

1

I have modified your class to process nested JsonArray type elements recursively, effectively flattening out the properties. You should be able to make slight modifications to this code as a basis to accomplish what you wish. Good luck.

import javax.json.*;
import java.io.FileReader;
import java.util.List;
import java.util.Set;

public class DataTest {
    public void processJson(String path) {
        JsonReader reader = null;
        try {
            reader = Json.createReader(new FileReader(path));
            JsonObject jsonObj = reader.readObject();
            processJsonObject(jsonObj);
        } catch (Exception ioe) {
            ioe.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
        }
    }

    private void processJsonObject(JsonObject jsonObj) {
        Set<String> keys = jsonObj.keySet();
        for (String key : keys) {
            JsonValue value = jsonObj.get(key);
            processJsonObject(key, value);
        }
    }

    private void processJsonObject(String key, JsonValue value){
       switch(value.getValueType()){
           case ARRAY:
               processJsonObject(key, (JsonArray)value);
               break;
           default:
               processJsonObject(key, (JsonString)value);
       }
    }

    private void processJsonObject(String key, JsonArray array) {
        System.out.println("Array:  key[" + key + "] = " + "An Array: " + array);
        List<JsonObject> elements = array.getValuesAs(JsonObject.class);
        for(JsonObject element: elements) {
            processJsonObject(element);
        }
    }

    private void processJsonObject(String key, JsonString value) {
        System.out.println("String: key[" + key + "] = " + value);
    }

    public static void main(String[] args) {
        DataTest test = new DataTest();
        test.processJson("/Data/Test/src/main/resources/elements.json");
    }
}
pczeus
  • 7,709
  • 4
  • 36
  • 51
  • I into some compile errors: processJsonObject(array); - JsonArray cannot be converted to JsonObject. and the compiler could not find a suitable method for processJsonObject(key, value); saying that JsonValue can not be converted to JsonArray or JsonString – Tyler Mar 18 '16 at 20:03
  • Well...I got caught in a Groovy trap. I do a lot of prototyping using Java within a Groovy script and in this case it behaved differently (and a bit mor e elegantly). Anyway, I have updated the answer with a pure Java implementation, which is slightly different. – pczeus Mar 18 '16 at 20:33
  • That's along the lines of what I was thinking too. Some type of IDE or similar tweaking the mechanics. At any rate, it's working, thank you for the help! – Tyler Mar 19 '16 at 17:39