You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Josson递归计算JSON对象至第二层级表达式

递归计算JSON对象中的表达式(基于Josson库)

问题说明

我们使用Josson库处理JSON对象,需要递归计算所有层级中包含**expression**子字段的节点,将表达式计算结果替换原节点。

原始JSON

{  
  "selectionModel": {    
    "dp_speed": "0",    
    "moc": "CI-0"  
  },  
  "data": {    
    "B": "220",    
    "h2": "1000",    
    "h6": "175",    
    "weight": {      
      "expression": "calc(B+h2)"    
    },    
    "height": {      
      "expression": "calc(B+h6)"    
    },    
    "columnPipe": {      
      "pipeTotalWeight": {        
        "expression": "calc(if(length==0,680,700),length:$.data.columnPipe.pipeTotalLength)"      
      },      
      "pipeTotalLength": 1200,      
      "PipeCapLiters": {        
        "expression": "calc(if(length==0,70,100),length:$.data.columnPipe.pipeTotalLength)"      
      },      
      "pipeTopPipeqty": 1    
    }  
  },  
  "tbl05FlangeMasterDischarge": {    
    "flangeId": 3835,    
    "flangetype": "RF",    
    "size": 150  
  }
}

期望输出

{  
  "selectionModel": {    
    "dp_speed": "0",    
    "moc": "CI-0"  
  },  
  "data": {    
    "B": "220",    
    "h2": "1000",    
    "h6": "175",    
    "weight": 1220.0,    
    "height": 395.0,    
    "columnPipe": {      
      "pipeTotalWeight": 700.0,      
      "pipeTotalLength": 1200,      
      "PipeCapLiters": 100.0,      
      "pipeTopPipeqty": 1    
    }  
  },  
  "tbl05FlangeMasterDischarge": {    
    "flangeId": 3835,    
    "flangetype": "RF",    
    "size": 150  
  }
}

当前问题

现有代码仅能处理第一层级的表达式(如data下的weight、height),无法递归处理更深层级(如data.columnPipe下的节点):

当前代码

String a = "{\"selectionModel\":{\"dp_speed\":\"0\",\"moc\":\"CI-0\"},\"data\":{\"B\":\"220\",\"h2\":\"1000\",\"h6\":\"175\",\"weight\":{\"expression\":\"calc(B+h2)\"},\"height\":{\"expression\":\"calc(B+h6)\"},\"columnPipe\":{\"pipeTotalWeight\":{\"expression\":\"calc(if(length==0,680,700),length:$.data.columnPipe.pipeTotalLength)\"},\"pipeTotalLength\":1200,\"PipeCapLiters\":{\"expression\":\"calc(if(length==0,70,100),length:$.data.columnPipe.pipeTotalLength)\"},\"pipeTopPipeqty\":1}},\"tbl05FlangeMasterDischarge\":{\"flangeId\":3835,\"flangetype\":\"RF\",\"size\":150}}";

Josson josson = Josson.fromJsonString(a);

String expression = josson.getString("entries()" + ".concat('field('," + "        key," + "        value.entries()"
                + "             .[isNotEmpty(value.expression)]*" + "             .concat('.field(',key,': eval(',key,'.expression))')"
                + "             .join()," + "        ')')" + ".join('.')");

System.out.println(expression);
System.out.println(josson.getNode(expression));

当前输出

field(selectionModel).field(data.field(weight: eval(weight.expression)).field(height: eval(height.expression))).field(tbl05FlangeMasterDischarge)

{"selectionModel":{"dp_speed":"0","moc":"CI-0"},"data":{"B":"220","h2":"1000","h6":"175","weight":1220.0,"height":395.0,"columnPipe":{"pipeTotalWeight":{"expression":"calc(if(length==0,680,700),length:$.data.columnPipe.pipeTotalLength)"},"pipeTotalLength":1200,"PipeCapLiters":{"expression":"calc(if(length==0,70,100),length:$.data.columnPipe.pipeTotalLength)"},"pipeTopPipeqty":1}},"tbl05FlangeMasterDischarge":{"flangeId":3835,"flangetype":"RF","size":150}}

解决方案

通过定义递归函数生成Josson表达式,实现全层级的表达式计算:

修改后的代码

String a = "{\"selectionModel\":{\"dp_speed\":\"0\",\"moc\":\"CI-0\"},\"data\":{\"B\":\"220\",\"h2\":\"1000\",\"h6\":\"175\",\"weight\":{\"expression\":\"calc(B+h2)\"},\"height\":{\"expression\":\"calc(B+h6)\"},\"columnPipe\":{\"pipeTotalWeight\":{\"expression\":\"calc(if(length==0,680,700),length:$.data.columnPipe.pipeTotalLength)\"},\"pipeTotalLength\":1200,\"PipeCapLiters\":{\"expression\":\"calc(if(length==0,70,100),length:$.data.columnPipe.pipeTotalLength)\"},\"pipeTopPipeqty\":1}},\"tbl05FlangeMasterDischarge\":{\"flangeId\":3835,\"flangetype\":\"RF\",\"size\":150}}";

Josson josson = Josson.fromJsonString(a);

// 定义递归函数,遍历所有层级对象处理表达式
String recursiveExpr = "def recurse(obj) {" +
        "  obj.entries().concat('field(', key, " +
        "    (value.type() == 'OBJECT' ? " +
        "      (value.entries().[isNotEmpty(value.expression)]*.concat('.field(', key, ': eval(', key, '.expression))').join() + recurse(value))" +
        "      : '')," +
        "    ')').join('.')" +
        "}";

// 执行递归函数生成完整处理表达式
String expression = josson.getString(recursiveExpr + "; recurse($)");

System.out.println(expression);
System.out.println(josson.getNode(expression));

逻辑说明

  1. 递归函数recurse(obj)会遍历对象的每个键值对:
    • 若值为对象类型,先处理当前层级的**expression**节点,再递归处理子对象
    • 自动拼接生成包含所有层级的field()链式表达式,嵌入eval()计算逻辑
  2. 最终生成的表达式会递归处理所有层级的表达式节点,得到符合预期的输出。

生成的目标表达式

field(selectionModel).field(data.field(weight: eval(weight.expression)).field(height: eval(height.expression)).field(columnPipe.field(pipeTotalWeight: eval(pipeTotalWeight.expression)).field(PipeCapLiters: eval(PipeCapLiters.expression)))).field(tbl05FlangeMasterDischarge)

内容的提问来源于stack exchange,提问作者Pranav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 14:14:59