JSONata是一款专门用于JSON数据查询、转换和处理的表达式语言,它支持通过路径表达式快速定位JSON中的目标字段,同时也可以通过特定的语法实现字段值的动态修改,在接口数据处理、配置动态更新等场景中应用十分广泛。

JSONata基础语法回顾
在使用JSONata修改值之前,需要先了解几个核心的基础语法:
- 路径定位:使用点号
.访问对象属性,使用方括号[]访问数组元素,比如user.info.name可以定位到user对象下info对象的name字段。 - 条件筛选:使用
[$condition]语法筛选符合条件的元素,比如items[price > 100]可以筛选出items数组中价格大于100的元素。 - 函数调用:JSONata内置了大量实用函数,比如
$string()用于类型转换,$merge()用于合并对象。
动态修改JSON值的实现思路
JSONata本身的设计定位是数据查询和转换,并不直接支持原地修改原JSON数据,通常的实现思路是:先通过路径表达式定位到需要修改的目标字段,再结合转换语法生成新的JSON结构,用新值替换原有字段的值,最终得到修改后的完整JSON。
基础修改示例
假设我们有如下原始JSON数据,需要把name字段的值修改为"李四":
{
"user": {
"id": 1,
"name": "张三",
"age": 25
}
}
对应的JSONata表达式如下:
{
"user": {
"id": user.id,
"name": "李四",
"age": user.age
}
}
执行该表达式后,会生成新的JSON,其中name字段已经被替换,其他字段保持不变。
动态路径修改示例
如果需要动态指定要修改的路径,比如根据传入的参数决定修改哪个字段,可以结合变量和路径拼接实现。假设我们需要动态修改user对象下的任意字段,传入的参数是{"field": "age", "value": 30},表达式可以这样写:
{
"user": $merge([
user,
{
$field: $value
}
])
}
这里使用$merge()函数合并原user对象和新的字段对象,通过变量$field动态指定要修改的字段名,$value指定新的值,执行后age字段会被修改为30。
数组元素动态修改示例
如果要修改数组中符合条件的元素值,比如把items数组中id为2的元素的status修改为"已发货",原始JSON如下:
{
"items": [
{"id": 1, "name": "商品A", "status": "待发货"},
{"id": 2, "name": "商品B", "status": "待发货"},
{"id": 3, "name": "商品C", "status": "待发货"}
]
}
对应的JSONata表达式如下:
{
"items": items ~> $map(function($item) {
$item.id = 2 ? $merge([$item, {"status": "已发货"}]) : $item
})
}
这里使用了$map()函数遍历数组,通过条件判断筛选出id为2的元素,再用$merge()函数修改其status字段,其他元素保持不变。
注意事项
- JSONata修改后返回的是新的JSON对象,不会修改原始数据,使用时需要接收返回结果。
- 路径表达式中的特殊字符字段名需要用方括号包裹,比如字段名包含空格时,需要用
["field name"]的形式访问。 - 动态拼接路径时要注意变量作用域,确保传入的变量在表达式执行时可以被正确读取。
实际应用场景示例
在接口返回数据处理的场景中,经常需要对返回的JSON做统一处理,比如给所有用户的name字段添加前缀"用户:":
{
"data": [
{"id": 1, "name": "张三"},
{"id": 2, "name": "李四"}
]
}
对应的JSONata表达式:
{
"data": data ~> $map(function($item) {
$merge([$item, {"name": "用户:" & $item.name}])
})
}
执行后所有name字段都会带上指定前缀,满足接口数据格式要求。