jsonmuledataweavemulesoftanypoint-studio

How to convert below json (which can have multiple nested objects) to required ouput using Dataweave?


Input:

     {
          "drag": {
            "misc": {
              "prog": {
                "ID": {
                  "type": "name",
                  "value": "ABC"
                },
                "ID": {
                  "type": "standard",
                  "value": "PQR"
                }
              }
            }
          },
          "peak": {
            "bird": {
              "tech": {
                "pl": {
                  "ID": {
                    "type": "room",
                    "value": "123"
                  },
                  "ID": {
                    "type": "sport",
                    "value": "football"
                  }
                }
              }
            }
          },
          "ID": {
            "type": "browser",
            "value": "google"
          },
          "ID": {
            "type": "day",
            "value": "Wednesday"
          }
        }

Required Output:

{
  "drag": {
    "misc": {
      "prog": {
        "ID": {
          "name": "ABC",
          "standard": "PQR"
        }
      }
    }
  },
  "peak": {
    "bird": {
      "tech": {
        "pl": {
          "ID": {
            "room": "123",
            "sport": "football"
          }
        }
      }
    }
  },
  "ID": {
    "browser": "google",
    "day": "Wednesday"
  }
}

To summarize the requirement, I need to consolidate ID key w.r.t type and value keys. Please note: This is just an example payload. Actual payload can have n number of nested objects. However, the ID will have same keys i.e. type and value. Manually structuring the payload is not an option.


Solution

  • Using a recursive function to map all objects, if an element has all keys with name "ID" then we map them to a single "ID" element with the key-values 'consolidated'. If not we just recursively apply the same logic to its children elements. All types other than Object are left as they are.

    %dw 2.0
    import * from dw::core::Arrays
    output application/json 
    
    fun mapProg(x, idKeyname) =
      x match {
        case o is Object -> 
            if (namesOf(o) every ($ == idKeyname))
                {
                    ID: o mapObject (($.'type'): $.value)
                }
            else
                (o mapObject ($$): mapProg($, idKeyname)) // recursively map child elements
        else -> x
      }
    ---
    mapProg(payload, "ID")
    

    Output:

    {
      "drag": {
        "misc": {
          "prog": {
            "ID": {
              "name": "ABC",
              "standard": "PQR"
            }
          }
        }
      },
      "peak": {
        "bird": {
          "tech": {
            "pl": {
              "ID": {
                "room": "123",
                "sport": "football"
              }
            }
          }
        }
      },
      "ID": {
        "type": "browser",
        "value": "google"
      },
      "ID": {
        "type": "day",
        "value": "Wednesday"
      }
    }