使用 Josson 动态递归求值 JSON 中嵌套表达式字段的完整教程

落瑶吖_5426

落瑶吖_5426

2026-03-10

437人浏览

原创

使用 Josson 动态递归求值 JSON 中嵌套表达式字段的完整教程

本文详解如何基于 Josson 库(集成 mXparser)对结构未知的 JSON 对象进行递归遍历与表达式求值,支持跨字段依赖(如 D 引用 C 的计算结果),并提供可自动构建转换表达式的通用方案。

本文详解如何基于 josson 库(集成 mxparser)对结构未知的 json 对象进行递归遍历与表达式求值,支持跨字段依赖(如 `d` 引用 `c` 的计算结果),并提供可自动构建转换表达式的通用方案。

在实际工程中,常需处理“配置即代码”型 JSON:部分字段为原始值(如数字、字符串),部分则为动态表达式(如 "calc(A+B,A:data.A,B:data.B)"),且表达式间存在依赖关系(D 依赖 C 的计算结果)。Josson 是一款功能强大的 Java JSON 查询与转换库,其 eval() 函数结合底层 mXparser 数学引擎,天然支持此类场景——但直接硬编码路径易出错、不可扩展,且需规避语法陷阱(如保留字冲突)与非法求值(如对 PDF 文件名执行 calc)。

✅ 核心原则:结构化表达式 + 按需求值

为安全、清晰地分离数据与逻辑,推荐采用 显式表达式对象 结构(如 "C": {"expression": "calc(A+B)"}),而非将表达式字符串直接作为字段值。这不仅避免了 C(mXparser 中为组合数函数)等保留字引发的 Calc syntax error,也使解析逻辑更鲁棒。

以下为标准处理流程:

1. 构建 Josson 实例并加载 JSON

String json = "{\n" +
    "  \"data\": {\n" +
    "    \"A\": 1688,\n" +
    "    \"B\": 1363,\n" +
    "    \"c\": {\"expression\": \"calc(A+B)\"},\n" +
    "    \"D\": {\"expression\": \"calc(B+c)\"},\n" +
    "    \"drg\": \"TEMPLATE(12).pdf\"\n" +
    "  },\n" +
    "  \"tbl02Modelmaster\": {\n" +
    "    \"A\": {\"expression\": \"calc(A+100,A:$.data.A)\"},\n" +
    "    \"stageType\": \"Multi\",\n" +
    "    \"isPowerConstraint\": true\n" +
    "  }\n" +
    "}";
Josson josson = Josson.fromJsonString(json);

⚠️ 注意:字段名改用小写 c 替代 C,彻底规避 mXparser 保留字冲突。

2. 手动编写转换表达式(适用于已知结构)

利用 Josson 的链式 field() 与 eval() 实现按依赖顺序求值:

JsonNode result = josson.getNode(
    "field(data" +
        ".field(c: eval(c.expression))" +   // 先算 c
        ".field(D: eval(D.expression))" +   // 再算 D(可引用 c)
    ")" +
    ".field(tbl02Modelmaster" +
        ".field(A: eval(A.expression))" +   // 独立计算 A
    ")"
);
System.out.println(result.toPrettyString());

输出中 c 和 D 已被替换为数值(3051.0, 4414.0),其他原始值保持不变。

3. 自动构建表达式(推荐:适配任意动态结构)

面对未知嵌套层级与字段名,需程序化生成 Josson 路径表达式。关键思路:递归扫描所有对象,识别含 expression 字段的节点,并为其生成 .field(KEY: eval(KEY.expression)) 子句。

// 自动提取所有需求值的字段路径
String transformExpr = josson.getString(
    "entries()" + // 遍历根级键值对
        ".concat('field('," +
            "key," + // 当前对象名(如 "data")
            "value.entries()" + // 进入该对象内部
                ".[value.expression != null]*" + // 筛选 value 为 {expression: "..."} 的项
                ".concat('.field(', key, ': eval(', key, '.expression))')" + // 生成求值子句
                ".join()," + // 合并所有子句
            "')" + // 闭合 field()
        ".join('.')" // 合并各顶层对象的 field()
);
System.out.println("Auto-generated expression: " + transformExpr);
// 输出: field(data.field(c: eval(c.expression)).field(D: eval(D.expression))).field(tbl02Modelmaster.field(A: eval(A.expression)))

// 执行动态表达式
JsonNode finalResult = josson.getNode(transformExpr);

此方法完全解耦业务逻辑与 JSON 结构,新增一个带 expression 的字段(如 "E": {"expression": "calc(c*D)"})后,无需修改 Java 代码,仅需更新 JSON 即可生效。

? 关键注意事项

  • 依赖顺序:Josson 按表达式书写顺序执行 eval,确保被依赖字段(如 c)的 field() 出现在依赖字段(如 D)之前。
  • 作用域规则:eval() 默认在当前对象上下文中执行。若需跨对象引用(如 tbl02Modelmaster.A 引用 data.A),必须显式指定路径(如 A: $.data.A),这已在示例中体现。
  • 错误防御:eval() 遇到非法表达式会抛异常。生产环境建议包裹 try-catch 并记录原始表达式,便于排查。
  • 性能考量:对超大 JSON,频繁调用 getNode() 可能有开销。若需多次变换,可预先编译表达式(Josson 支持 Josson.compile())。

通过上述方案,你已掌握一种兼具健壮性、扩展性与专业性的 JSON 表达式求值范式——它不再受限于固定 schema,而是让 JSON 本身成为可执行的配置脚本。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2023.08.07

2255

5

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.23

3642

1

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

2023.10.13

1216

3

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

2025.09.10

4199

7

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

1049

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

3320

5

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.03

1878

5

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.04

3004

5

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

2023.10.24

6284

49

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.7万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 134.1万人学习