Tony
Tony

Reputation: 2774

MuleSoft Dataweave JSON to XML, reintegrating attributes from writeAttributes=true

I converted an XML snippet to JSON using the writeAttributes=true property.

XML:

<family surname="Simpsons">
  <father age="42">Homer</father>
  <mother age="41">Marge</mother>
  <children>
    <child age="9">Bart</child>
    <child age="8">Lisa</child>
    <child age="1">Maggie</child>
  </children>
</family>

DataWeave:

%dw 2.0
output application/json 
   writeAttributes=true, 
   duplicateKeyAsArray=true
---
payload

Resulting JSON:

{
  "family": {
    "@surname": "Simpsons",
    "father": {
      "@age": "42",
      "__text": "Homer"
    },
    "mother": {
      "@age": "41",
      "__text": "Marge"
    },
    "children": {
      "child": [
        {
          "@age": "9",
          "__text": "Bart"
        },
        {
          "@age": "8",
          "__text": "Lisa"
        },
        {
          "@age": "1",
          "__text": "Maggie"
        }
      ]
    }
  }
}

XML attributes and values are retained in the JSON through use of modified keys: "@key" for the attribute, and "__text" for the value. While the operation to go from XML to JSON is straightforward with the writeAttributes writer property, there doesn't seem to be an equivalent to do the reverse. Using this result format, I want to convert similar JSON to the original XML.

What's the simplest way to transform JSON back to XML and reintegrate the attributes?


Edit:

Using aled's transform here on the resulting JSON payload above, I was able to get a close result, but the child array elements didn't reacquire the age attribute.

aled's DataWeave:

%dw 2.0
output application/xml
fun getAttributes(x) =
   x match {
      case is Object -> x filterObject ($$ as String startsWith "@") 
         mapObject ((value, key, index) -> (key[1 to -1] ): value)
      else -> $
   }
fun convertToAttributes(x) =
   x match  {
      case is Object -> x filterObject !($$ as String startsWith "@")
         mapObject ($$) @((getAttributes($))): convertToAttributes($)
      case is Array -> x map convertToAttributes($)
      else -> $
   }
---
convertToAttributes(payload)

Resulting XML:

<?xml version='1.0' encoding='UTF-8'?>
<family surname="Simpsons">
  <father age="42">Homer</father>
  <mother age="41">Marge</mother>
  <children>
    <child>Bart</child>
    <child>Lisa</child>
    <child>Maggie</child>
  </children>
</family>

__text somehow becomes the value during the transform.

I'm not sure why it's not picking up the age in the array.

Upvotes: 0

Views: 112

Answers (1)

Fredie pulgoso
Fredie pulgoso

Reputation: 1

Try this:

%dw 2.0
output application/xml
---
{
    family @(surname: payload.family.'@surname'): {
        father @(age: payload.family.father.'@age'): 
payload.family.father.'__text',
        mother @(age: payload.family.mother.'@age'): 
payload.family.mother.'__text',
        children: {
            (payload.family.children.child map (child) -> {
                child @(age: child.'@age'): child.'__text'
            })
        }
    }
}

Upvotes: 0

Related Questions