
Josson 的 calc() 函数底层依赖 mXparser 数学解析器,不支持直接在表达式中进行字符串比较;需先通过 if() 或 caseValue() 提取数值,再传入 calc() 进行运算。
josson 的 `calc()` 函数底层依赖 mxparser 数学解析器,不支持直接在表达式中进行字符串比较;需先通过 `if()` 或 `casevalue()` 提取数值,再传入 `calc()` 进行运算。
在使用 Josson 库进行 JSON 路径计算时,开发者常误以为 calc() 函数可直接嵌入字符串逻辑(如 if(sp=="PN16", ...)),但实际其首参数必须是纯数学表达式——mXparser 仅接受数值、变量和标准算术/逻辑运算符,不支持字符串字面量比较或字符串类型变量参与条件分支。因此,原始写法:
String expression3 = "calc(if(sp==\"PN16\",350*2,400*2),sp:$.data.flange.specification)";
会触发 IllegalArgumentException: Invalid function call calc() : Calc syntax error,因为 if(sp=="PN16",...) 不是合法的 mXparser 表达式。
✅ 正确做法是:将条件判断与数值提取前置到 calc() 外部,仅把最终得到的数字传入 calc() 执行运算。例如:
String a = "{\"pressureStage\":1,\"data\":{\"flange\":{\"specification\":\"PN 16\"}}}";
Josson josson = Josson.fromJsonString(a);
// ✅ 正确:用 Josson 内置 if() 提取数值,再交由 calc() 计算
String expression = "calc(sp * 2, sp: $.data.flange.if([specification='PN 16'], 350, 400))";
System.out.println(josson.getNode(expression)); // 输出:700⚠️ 注意:
if([condition], then, else)是 Josson 原生函数,支持字符串比较(注意空格敏感,"PN 16"≠"PN16"),且返回数值类型,完美适配calc()。
对于多分支场景,推荐使用更清晰、可维护性更强的 caseValue():
// ✅ 多条件映射示例(支持空格、大小写、默认值)
String multiExpr = "$.data.flange.specification.caseValue(" +
"'PN 16', calc(350 * 2)," +
"'PN 40', calc(400 * 2)," +
"'ANSI B16.5 CLASS150', calc(260 * 3)," +
"calc(265 * 4)" + // 默认分支
")";
System.out.println(josson.getNode(multiExpr)); // 根据 specification 值输出对应计算结果? 关键总结:
-
calc()的第一个参数必须是纯数学表达式(如x*2,a+b),不可含字符串操作; - 字符串判断应使用 Josson 原生函数
if()或caseValue()完成,它们在 JSON 上下文中执行,返回数值后才进入calc(); - 条件中的字符串值需严格匹配(包括空格、大小写),建议预处理或使用正则
match()函数增强鲁棒性; - 所有
calc(...)调用均自动启用 mXparser,支持函数(sin(),log10())、常量(pi,e)及自定义变量。
遵循此模式,即可安全、高效地在 Josson 中实现“基于字符串配置的动态数值计算”。

















