java 使用变量名为Josson的表达式对JSON对象求值

aiazj4mn  于 2023-01-11  发布在  Java
关注(0)|答案(2)|浏览(132)

我们需要在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。

tjjdgumg

tjjdgumg1#

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

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;

    }

}
yb3bgrhw

yb3bgrhw2#

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]))" +
    ")");

建议将所有表达式分组到预定义数组中

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(exp@.eval())");
System.out.println(node.toPrettyString());
  • 产出 *
{
  "a" : 100,
  "b" : 200,
  "c" : 300,
  "f" : {
    "g" : 100,
    "h" : 200
  },
  "exp" : [ 400.0, 300.0, "100+300=400.0", "100+200=300.0" ]
}

相关问题