【问题标题】:Evaluate JSON object with expression with variable name, Josson使用变量名 Josson 的表达式评估 JSON 对象
【发布时间】:2023-01-10 13:39:39
【问题描述】:

我们需要在 java 中评估 JSON 对象表达式。

我们有以下源 JSON 对象

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

我们需要输出这种格式

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

我们尝试了

我们试过 https://github.com/octomix/josson 但那更像是一个过滤 JSON。

【问题讨论】:

    标签: java json spring hibernate extjs


    【解决方案1】:

    希望这可以帮助。代码本身中提到了所有必要的信息。

    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;
    
        }
    
    }
    

    【讨论】:

      【解决方案2】:
      Josson josson = Josson.fromJsonString(jsonString);
      JsonNode node = josson.getNode("field(d:eval(d), f.field(i:eval(i)))");
      System.out.println(node.toPrettyString());
      

      输出

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

      对于未知结构

      该解决方案假设

      • 评价语句包含()
      • 每一关只有一个评价语句
      • 你需要知道下一级孩子的名字(在这个例子中是f

      转型

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

      【讨论】:

      • 您好@Raymond,感谢您的回答。这解决了我们知道 json 结构的问题。但是,您能否建议更通用的方法,其中 json 结构未知并且可以迭代 json 并且可以在使用 calc 和 concat 等公式的任何地方完成 eval。同时保持json的深度
      猜你喜欢
      • 2023-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多