Reputation: 2774
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
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