英文:
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 = "{'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
得分: 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("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" ]
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论