如何使用DataWeave更新运算符动态定位嵌套节点?
解决DataWeave中动态嵌套路径的update操作问题
要处理动态传入的深层嵌套路径,不能直接把完整路径字符串用插值方式传入update的选择器——DataWeave会把整个字符串当作单个字段名,而非嵌套路径。正确做法是先将路径拆分为字段数组,再通过遍历或递归方式逐层定位目标节点完成更新。
方法1:用reduce构建动态路径更新
先把路径字符串按.分割成字段数组,再通过reduce从根节点开始逐层深入,最终修改目标节点的值:
%dw 2.0 var node = "person.contact.phone.cell.work" var pathSegments = splitBy(node, ".") // 拆分为["person", "contact", "phone", "cell", "work"] output application/json --- pathSegments reduce ((segment, acc = payload) -> acc update { case s at ."$(segment)" -> if (segment == pathSegments[-1]) "404-555-3456" else s } )
方法2:用递归函数处理动态路径
如果需要更灵活的逻辑(比如支持删除节点),可以编写递归函数遍历路径并更新:
%dw 2.0 var node = "person.contact.phone.cell.work" var pathSegments = splitBy(node, ".") fun updateNested(obj, path, newValue) = if (sizeOf(path) == 1) obj update { case s at ."$(path[0])" -> newValue } else obj update { case s at ."$(path[0])" -> updateNested(s, path[1 to -1], newValue) } output application/json --- updateNested(payload, pathSegments, "404-555-3456")
验证结果
两种方法处理给定输入后,输出均为:
{ "person": { "name": "Joe Blow", "contact": { "email": "joe.blow@dot.com", "phone": { "cell": { "personal": "404-555-1234", "work": "404-555-3456" } } } } }
扩展:删除目标节点
如果需要删除动态路径指向的节点,可修改递归函数实现:
%dw 2.0 var node = "person.contact.phone.cell.work" var pathSegments = splitBy(node, ".") fun deleteNested(obj, path) = if (sizeOf(path) == 1) obj - path[0] else obj update { case s at ."$(path[0])" -> deleteNested(s, path[1 to -1]) } output application/json --- deleteNested(payload, pathSegments)
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

