使用变量名Josson评估JSON对象中的表达式。

huangapple go评论75阅读模式
英文:

Evaluate JSON object with expression with variable name, Josson

问题

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

英文:

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.

答案1

得分: 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) {

        // 将字符串解析为JSONObject
        JSONObject jsonObject = new JSONObject(inputString);
        Iterator<String> keys = jsonObject.keys();

        // 遍历键
        while (keys.hasNext()) {

            String key = keys.next();
            Object value = jsonObject.get(key);

            if (value instanceof Integer) {
                // 普通值
            } else if (value instanceof String) {
                // 'calc(x+y)'字符串

                // 从calc(a+c)中提取在"("和")"之间的所有内容
                Pattern pattern = Pattern.compile("\\((.*?)\\)");
                Matcher m = pattern.matcher(value.toString());

                while (m.find()) {
                    // a+c
                    String evalString = m.group(1);

                    // 以'+'拆分
                    String[] splitEvalString = evalString.split("\\+");

                    // 检查是否找到了确切的2个值
                    if (splitEvalString.length == 2) {
                        value = (Integer) jsonObject.get(splitEvalString[0])
                                + (Integer) jsonObject.get(splitEvalString[1]);
                    }
                }
            } else if (value instanceof JSONObject) {
                // 嵌套的JSONObject
                // 递归调用此方法
                value = parseJSONValue(value.toString(), new JSONObject());
            }

            // 添加到新的JSON对象
            resultJSON.put(key, value);
        }

        return resultJSON;
    }
}
英文:

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 = &quot;{&#39;a&#39;: 100, &#39;b&#39;: 200, &#39;c&#39;: 300, &#39;d&#39;: &#39;calc(a+c)&#39;, &#39;f&#39;: {&#39;g&#39;: 100, &#39;h&#39;: 200, &#39;i&#39;: &#39;calc(g+h)&#39;} }&quot;;
JSONObject newJSON = parseJSONValue(inputString, new JSONObject());
System.out.println(newJSON.toString());
// {&quot;a&quot;:100,&quot;b&quot;:200,&quot;c&quot;:300,&quot;d&quot;:400,&quot;f&quot;:{&quot;g&quot;:100,&quot;h&quot;:200,&quot;i&quot;:300}}
}
public static JSONObject parseJSONValue(String inputString, JSONObject resultJSON) {
// Parse your string as JSONObject
JSONObject jsonObject = new JSONObject(inputString);
Iterator&lt;String&gt; 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 &#39;calc(x+y)&#39; strings
// Extract everything between &quot;(&quot; and &quot;)&quot; from calc(a+c)
Pattern pattern = Pattern.compile(&quot;\\((.*?)\\)&quot;);
Matcher m = pattern.matcher(value.toString());
while (m.find()) {
// a+c
String evalString = m.group(1);
// Split by &#39;+&#39;
String[] splitEvalString = evalString.split(&quot;\\+&quot;);
// 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

得分: 0

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(exp@.eval())");
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" ]
}

英文:
Josson josson = Josson.fromJsonString(jsonString);
JsonNode node = josson.getNode(&quot;field(d:eval(d), f.field(i:eval(i)))&quot;);
System.out.println(node.toPrettyString());

Output

{
&quot;a&quot; : 100,
&quot;b&quot; : 200,
&quot;c&quot; : 300,
&quot;d&quot; : 400.0,
&quot;f&quot; : {
&quot;g&quot; : 100,
&quot;h&quot; : 200,
&quot;i&quot; : 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(
&quot;let($p: &#39;.+\\(.*\\).*&#39;)&quot; +
&quot;.field(entries().[value =~ $p].key :: eval(*[value =~ $p]),&quot; +
&quot;       f.field(entries().[value =~ $p].key :: eval(*[value =~ $p]))&quot; +
&quot;)&quot;);

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

Josson josson = Josson.fromJsonString(
&quot;{&quot; +
&quot;  \&quot;a\&quot;: 100,&quot; +
&quot;  \&quot;b\&quot;: 200,&quot; +
&quot;  \&quot;c\&quot;: 300,&quot; +
&quot;  \&quot;f\&quot;: {&quot; +
&quot;    \&quot;g\&quot;: 100,&quot; +
&quot;    \&quot;h\&quot;: 200&quot; +
&quot;  },&quot; +
&quot;  \&quot;exp\&quot;: [\&quot;$.calc(a+c)\&quot;,&quot; +
&quot;            \&quot;$.calc(g+h, g:f.g, h:f.h)\&quot;,&quot; +
&quot;            \&quot;$.concat(a, &#39;+&#39;, c, &#39;=&#39;, calc(a+c))\&quot;,&quot; +
&quot;            \&quot;$.concat(f.g, &#39;+&#39;, f.h, &#39;=&#39;, calc(g+h, g:f.g, h:f.h))\&quot;&quot; +
&quot;           ]&quot; +
&quot;}&quot;);
JsonNode node = josson.getNode(&quot;field(exp@.eval())&quot;);
System.out.println(node.toPrettyString());

Output

{
&quot;a&quot; : 100,
&quot;b&quot; : 200,
&quot;c&quot; : 300,
&quot;f&quot; : {
&quot;g&quot; : 100,
&quot;h&quot; : 200
},
&quot;exp&quot; : [ 400.0, 300.0, &quot;100+300=400.0&quot;, &quot;100+200=300.0&quot; ]
}

huangapple
  • 本文由 发表于 2023年1月9日 12:11:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75053114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定