0

I have a payload in XML format, and I need to convert it to JSON. The XML contains many key-value pairs and also a lot of attributes, and I need those attributes to be included in the JSON as well.

<CustomData>

  <CustomIdentifier attribute1="value1" attribute2="value2">

    test  </CustomIdentifier>

</CustomData>

This one output writeAttributes=true makes __text but I don't want have it. I want to change this dynamically so that this __text becomes a key. I have more attributes and I can't have everywhere __text

example:

{

"CustomData": {

"CustomIdentifier": {

"@attribute1": "value1",

"@attribute2": "value2",

"CustomIdentifier": "test"

}

}

}
2
  • The format is incorrect making the question harder to read. The code block format three backticks delimiter have to be in a separate line from your text to work. Commented Dec 4, 2024 at 13:53
  • I fixed it for you. Next time be careful with the formatting. Commented Dec 4, 2024 at 16:52

1 Answer 1

1

The built-in feature doesn't allow for customization of the output. To achieve the expected output you need a custom transformation. It can be implemented by creating a recursive function that when it receives an object with attributes outputs an object with the current value under a new key with the same name than the existing key, and concatenating the attributes as new key-values. Otherwise return the value applying recursively the same transformation. Any other type is returning as is. My implementation includes mapping each element of an array though that there are no arrays in XML inputs. It should work with other format but I haven't tested it.

Example

Function:

%dw 2.0
output application/json 
fun writeWithAttributes(x) = x match {
    case o is Object -> 
        o mapObject ((value, key, index) ->
            if (isEmpty(key.@)) // if there are no attributes just return the same key and transform the value
                { (key): writeWithAttributes(value) } 
            else // if there are attributes add a new child object with the keys collected and the value repeating the same key.
                {
                    (key): { 
                        (key): writeWithAttributes(value), 
                        (key.@ mapObject ("@"++$$ as String): $) 
                    }
                } 
        )

    case a is Array -> a map writeWithAttributes($)
    else -> x
  }
---
writeWithAttributes(payload) 

Input:

<CustomData>
  <CustomIdentifier attribute1="value1" attribute2="value2">test</CustomIdentifier>
</CustomData>

Output:

{
  "CustomData": {
    "CustomIdentifier": {
      "CustomIdentifier": "test",
      "@attribute1": "value1",
      "@attribute2": "value2"
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.