skip to Main Content

We need to evaluate JSON object expressions in java.

We have the following source JSON object

{
  "a": 100,
  "b": 200,
  "c": 300,
  "d": "calc(a+c)",
  "f": {
    "g": 100,
    "h": 200,
    "i": "calc(g+h)"
  }
}

we need output this format

{
  "a": 100,
  "b": 200,
  "c": 300,
  "d": 400,
   "f": {
    "g": 100,
    "h": 200,
    "i": 300
  }
}

We tried

we tried https://github.com/octomix/josson but that is more of a filtering JSON.

2

Answers


  1. Hope this helps. All the necessary information is mentioned inside the code itself.

    import java.util.Iterator;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import org.json.JSONObject;
    
    public class Main {
    
        public static void main(String[] args) {
    
            String inputString = "{'a': 100, 'b': 200, 'c': 300, 'd': 'calc(a+c)', 'f': {'g': 100, 'h': 200, 'i': 'calc(g+h)'} }";
    
            JSONObject newJSON = parseJSONValue(inputString, new JSONObject());
    
            System.out.println(newJSON.toString());
            // {"a":100,"b":200,"c":300,"d":400,"f":{"g":100,"h":200,"i":300}}
    
        }
    
        public static JSONObject parseJSONValue(String inputString, JSONObject resultJSON) {
    
            // Parse your string as JSONObject
            JSONObject jsonObject = new JSONObject(inputString);
            Iterator<String> keys = jsonObject.keys();
    
            // Iterate through your keys
            while (keys.hasNext()) {
    
                String key = keys.next();
                Object value = jsonObject.get(key);
    
                if (value instanceof Integer) {
    
                    // Your normal values
    
                } else if (value instanceof String) {
    
                    // Your 'calc(x+y)' strings
    
                    // Extract everything between "(" and ")" from calc(a+c)
                    Pattern pattern = Pattern.compile("\((.*?)\)");
                    Matcher m = pattern.matcher(value.toString());
    
                    while (m.find()) {
    
                        // a+c
                        String evalString = m.group(1);
    
                        // Split by '+'
                        String[] splitEvalString = evalString.split("\+");
    
                        // Check if exactly 2 values are found
                        if (splitEvalString.length == 2) {
                            value = (Integer) jsonObject.get(splitEvalString[0])
                                    + (Integer) jsonObject.get(splitEvalString[1]);
                        }
    
                    }
    
                } else if (value instanceof JSONObject) {
                    // Your nested JSONObjects
                    // Recursively call this method
                    value = parseJSONValue(value.toString(), new JSONObject());
                }
    
                // Add to your new JSON Object
                resultJSON.put(key, value);
    
            }
    
            return resultJSON;
    
        }
    
    }
    
    Login or Signup to reply.
  2. Josson josson = Josson.fromJsonString(jsonString);
    JsonNode node = josson.getNode("field(d:eval(d), f.field(i:eval(i)))");
    System.out.println(node.toPrettyString());
    

    Output

    {
      "a" : 100,
      "b" : 200,
      "c" : 300,
      "d" : 400.0,
      "f" : {
        "g" : 100,
        "h" : 200,
        "i" : 300.0
      }
    }
    

    For unknown structure

    This solution assumes

    • the evaluation statement contains ()
    • there is only one evaluation statement in each level
    • you need to know the next level child name (f in this example)

    Transformation

    JsonNode node = josson.getNode(
        "let($p: '.+\(.*\).*')" +
        ".field(entries().[value =~ $p].key :: eval(*[value =~ $p])," +
        "       f.field(entries().[value =~ $p].key :: eval(*[value =~ $p]))" +
        ")");
    

    Suggest to group all the expressions in a pre-defined array

    Josson josson = Josson.fromJsonString(
        "{" +
        "  "a": 100," +
        "  "b": 200," +
        "  "c": 300," +
        "  "f": {" +
        "    "g": 100," +
        "    "h": 200" +
        "  }," +
        "  "exp": ["$.calc(a+c)"," +
        "            "$.calc(g+h, g:f.g, h:f.h)"," +
        "            "$.concat(a, '+', c, '=', calc(a+c))"," +
        "            "$.concat(f.g, '+', f.h, '=', calc(g+h, g:f.g, h:f.h))"" +
        "           ]" +
        "}");
    JsonNode node = josson.getNode("field([email protected]())");
    System.out.println(node.toPrettyString());
    

    Output

    {
      "a" : 100,
      "b" : 200,
      "c" : 300,
      "f" : {
        "g" : 100,
        "h" : 200
      },
      "exp" : [ 400.0, 300.0, "100+300=400.0", "100+200=300.0" ]
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search