Reputation: 1
I have a XML file which has nested elements and few elements has attributes to that. I want to convert this XML to json using dataweave 2.0 and the json has to contain the attributes.
Using the json generated from previous step, I want to recreate the original XML
Ex: <elem1>
<elem2 attr=Val>
<elem3 attr=Val>
</elem3>
</elem2>
</elem1>
Thanks in advance
Upvotes: 0
Views: 654
Reputation: 4303
Using Christian's approach , you could update the script to remove "@" from the attribute keys:
%dw 2.0
output application/xml
fun collectAttributes(elem:Object) =
elem filterObject ((value, key, index) -> key contains "@" )
fun putAttributes(elem: Object) =
elem mapObject ((value, key, index) -> value match {
case is Object -> do {
var attr = (collectAttributes(value))
var attrfinal = attr mapObject {
($$ replace "@" with ""):(($))
}
var withoutAttr = value -- attr
---
(key) @((attrfinal)):
if (keysOf(withoutAttr) contains "__text" as Key)
withoutAttr."__text"
else
putAttributes(withoutAttr)
}
else -> (key): value
})
---
putAttributes(payload)
Upvotes: 2
Reputation: 692
You could try using this script for converting back to xml
%dw 2.0
output application/xml writeDeclaration=false
fun json2xml(data) = data mapObject (v, k, i) -> {
((k) @(
(
if(v is Object and !isEmpty(searchForAttr(v))) searchForAttr(v)
else null
)
): v match {
case is Object -> if(namesOf(v) contains("__text")) searchForText(v) else json2xml(v)
else -> v
}) if (!(k contains "@") and !(k contains "__text"))
}
fun searchForAttr(v) = v mapObject {
(($$[1 to -1]): $) if(($$ as String) startsWith("@"))
}
fun searchForText(v) = v mapObject {
(($$):$) if(($$ as String) == "__text")
} pluck $
---
json2xml(payload)
I tried it with a much more complex xml structure and it did convert back to the original xml, however the initial conversion to JSON (using the writeAttributes
option) leaves out xml namespaces so if your original input has namespaces may need to go another route with the JSON conversion.
Upvotes: 2
Reputation: 568
JSON with Attributes to XML with Attributes:
%dw 2.0
output application/xml
fun collectAttributes(elem:Object) =
elem filterObject ((value, key, index) -> key contains "@" )
fun putAttributes(elem: Object) =
elem mapObject ((value, key, index) -> value match {
case is Object -> do {
var attr = collectAttributes(value)
var withoutAttr = value -- attr
---
(key) @((attr)):
if (keysOf(withoutAttr) contains "__text" as Key)
withoutAttr."__text"
else
putAttributes(withoutAttr)
}
else -> (key): value
})
---
putAttributes(payload)
I'm not sure if it is fully generalized to take every JSON with Attributes, but works in your case.
XML to JSON with Attributes:
You could try the writer property writeAttributes
.
%dw 2.0
output application/json writeAttributes=true
---
payload
https://docs.mulesoft.com/mule-runtime/4.3/dataweave-formats-json#properties
Upvotes: 2