Search code examples
javajsoncommand-promptnotepad

java - javax.json - How to check if a value is a string


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.


Solution

  • 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");
        }
    }