DataWeave合并JSON时无法移除嵌套对象中null值的问题
DataWeave合并JSON时移除嵌套对象中指定null字段的问题解决
问题场景
需要合并payload与patch两个JSON对象,规则如下:
- 用
patch的字段值覆盖payload对应字段(空字符串等非null值正常保留) - 若
patch中某字段值为null,则移除payload中对应的该字段 - 嵌套对象需遵循同样规则
但现有代码仅能处理顶层字段的null移除,嵌套对象location-1中的pin字段(patch中设为null)无法被移除,不符合预期输出。
输入Payload
{ "firstname":"John", "lastname":"Sam", "city": "San Jose", "path": "additional", "location-1": { "address": "USA", "pin": null }, "location-2": { "address": null, "place": "abc", "pin": null } }
现有DataWeave代码
%dw 2.0 output application/json import mergeWith from dw::core::Objects var patch = { lastname:"Courtney", age:"18", path: "", company: "MR", firstname: null, city: null, "location-1": { "address": "USA", "pin": null } } --- (payload mergeWith ((patch)) filterObject ($ != null ))
预期输出
{ "lastname": "Courtney", "age": "18", "path": "", "company": "MR", "location-1": { "address": "USA" }, "location-2": { "address": null, "place": "abc", "pin": null } }
问题原因
filterObject ($ != null)仅作用于顶层键值对,嵌套对象本身不属于null,会被完整保留,其内部的null字段不会被过滤。同时要注意:我们只需要移除patch中明确设置为null的字段,payload原生的null字段(如location-2内的字段)需保留,不能全局过滤所有null。
解决方案
自定义递归合并函数,处理对象的嵌套层级,精准移除patch中设为null的字段:
%dw 2.0 output application/json // 递归合并并移除patch中指定为null的字段 fun mergeAndCleanNull(payload: Any, patch: Any): Any = if (payload is Object and patch is Object) patch reduce ((patchVal, patchKey) -> if (patchVal == null) // patch字段为null,移除payload对应字段 payload - patchKey else // 递归处理嵌套对象,非对象类型直接覆盖 payload ++ { (patchKey): mergeAndCleanNull(payload[patchKey] default {}, patchVal) } ) else if (patch != null) // 非对象类型,patch值非null则覆盖 patch else // patch值为null,保留原payload内容 payload var patch = { lastname:"Courtney", age:"18", path: "", company: "MR", firstname: null, city: null, "location-1": { "address": "USA", "pin": null } } --- mergeAndCleanNull(payload, patch)
函数逻辑说明
- 递归判断对象类型:若
payload和patch均为对象,遍历patch的每个键值对 - 若
patch字段值为null,直接从payload中移除对应键 - 若
patch字段值为对象,递归调用函数处理嵌套层级的合并与null移除 - 非对象类型(字符串、数字等):若
patch值非null则覆盖payload,否则保留原内容
运行该代码后,会精准移除所有patch中设为null的字段(包括顶层的firstname、city,以及嵌套的location-1.pin),同时保留payload原生的null字段。
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

