0

I have a JSON payload that I need to convert into an XML. However that JSON payload has many fields starting with '@' which are supposed to be the XML attributes. So when I converted those into XML the '@" is being attached to each xml tag as a field(e.g. <@id>1495161</@id>). Each field with '@' is supposed to be the XML attribute and should not come as indivial XML filed/tag after the conversion. Please see my code and output vs the expected output. Notice how all the fields with @ are transformed into xml tag. But I want all these fields with @ to transform into XML attributes.

Sample Request:

{
    "trans": {
        "@id": "1495144",
        "@TPId": "4aec",
        "@change": "0",
        "@count": "1",
        "@dateStamp": "2024-08-02T03:07:48",
        "data": {
            "@id": "d7D173564C5F14FF2AD08D621C188AF19",
                "StateFlag": "0",
                "DCC": "B",
                "LastName": "MMNGorthy",
                "Name": "Scott",
                "Structure": "NonProfit",
                "BusinessType": "Engineering",
                "meams": "AI",
                "Count": "0",
                "CTier": "000",
                "CTCond": "111",
                "CTPl": "222",
                "DO": "1",
                "AuthObject": "0"
            }
        }
    }

Code:

%dw 2.0
output application/xml
ns ns0 http://Test.Sample.Data/1.0
---

    ns0#trans: payload.trans

output from my code:

<?xml version='1.0' encoding='UTF-8'?>
<ns0:trans xmlns:ns0="http://Test.Sample.Data/1.0">
  <@id>1495144</@id>
  <@TPId>4aec</@TPId>
  <@change>0</@change>
  <@count>1</@count>
  <@dateStamp>2024-08-02T03:07:48</@dateStamp>
  <data>
    <@id>d7D173564C5F14FF2AD08D621C188AF19</@id>
    <StateFlag>0</StateFlag>
    <DCC>B</DCC>
    <LastName>MMNGorthy</LastName>
    <Name>Scott</Name>
    <Structure>NonProfit</Structure>
    <BusinessType>Engineering</BusinessType>
    <meams>AI</meams>
    <Count>0</Count>
    <CTier>000</CTier>
    <CTCond>111</CTCond>
    <CTPl>222</CTPl>
    <DO>1</DO>
    <AuthObject>0</AuthObject>
  </data>
</ns0:trans>

Expected output:

  <?xml version='1.0' encoding='UTF-8'?>
<ns0:trans xmlns:ns0="http://Test.Sample.data/1.0" id="1495144" TPId='4aec' change='0' count='1' dateStamp="2024-08-02T03:07:48">
    <data id="FF2AD08D621">
        <StateFlag>0</StateFlag>
        <DCC>B</DCC>
        <LastName>MMNGorthy</LastName>
        <Name>Scott</Name>
        <Structure>NonProfit</Structure>
        <BusinessType>Engineering</BusinessType>
        <meams>AI</meams>
        <Count>0</Count>
        <CTier>000</CTier>
        <CTCond>111</CTCond>
        <CTPl>222</CTPl>
        <DO>1</DO>
        <AuthObject>0</AuthObject>
    </data>
</ns0:trans>
10
  • 1
    Please add the code used for the conversion. It will probably need to add code to remove the @ symbol. Commented Mar 17 at 16:54
  • "the '@" is being attached to each xml tag as a field(e.g. <@id>1495161</@id>" the output you are showing doesn't has any tags with @. Show the actual answer and the expected answer for the same input. Commented Mar 17 at 17:43
  • Also please indent correctly the data. Commented Mar 17 at 17:50
  • Sorry about the confusion. The output I mentioned in my question is the expected output. Notice how all the fields with @ are transformed into XML attributes. Actually the input JSON was probably transformed from some XML and usually when you transform an XML to JSON the XML attributes does transforms to @. But my requirement is to take this JSON and convert to XML. Here is the code and my output %dw 2.0 output application/xml ns ns0 Test.Sample.Data/1.0 --- ns0#trans: payload.trans Commented Mar 17 at 18:27
  • Please copy or type the text into the question. Reserve the use of images for diagrams or demonstrating rendering bugs, things that are impossible to describe accurately via text. Code or sample data in images can't be copied and pasted in order to search about a problem or reproduce it. For more details read the Meta FAQ entry Why not upload images of code/errors when asking a question? Commented Mar 17 at 18:36

1 Answer 1

2

To add an attribute, you need to define them as:

xmlElem @(att1: val1, att2: val2): xmlValue

Notice that the value inside the @() is not an object but the deconstructed version of the object. For example, if you have:

var jsonObject = {att1: val1, att2: val2}

You cannot directly write:

xmlElem @(jsonObject): xmlValue

Instead, you need to deconstruct it using ():

xmlElem @((jsonObject)): xmlValue

Now, for your use case, you need to make the output dynamic. You can use the following transformation. Most of the functions are self explanatory.

%dw 2.0
output application/xml
ns ns0 http://Test.Sample.Data/1.0

fun getAttributes(jsonObject: Object) = 
    jsonObject 
        filterObject ($$ startsWith "@")
        mapObject ((value, key) -> (key[1 to -1]): value) //remove first char from key i.e. @

fun getNonAttributes(jsonObject: Object) = 
    jsonObject 
        filterObject !($$ startsWith "@")

fun fromJsonToXml(json) = 
    json mapObject ((value, key) -> 
        if(value is Object) (key) @((getAttributes(value))): fromJsonToXml(getNonAttributes(value)) // Attributes are applied using `@( (getAttributes(value)) )`. Notice how the function call is further wrapped around `()` to deconstruct the output
        else (key): value
    )
---
// following is to add namespace
fromJsonToXml(payload) 
then ((resultWithoutNS) -> 
    ns0#trans @((resultWithoutNS.trans.@)): resultWithoutNS.trans
)
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.