最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

mule - JSON conversion to XML using attributes and namespaces - Stack Overflow

programmeradmin2浏览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="/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>

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>
Share Improve this question edited Mar 17 at 18:48 Zak01 asked Mar 17 at 16:27 Zak01Zak01 335 bronze badges 10
  • 1 Please add the code used for the conversion. It will probably need to add code to remove the @ symbol. – LMC 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. – aled Commented Mar 17 at 17:43
  • Also please indent correctly the data. – aled 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 – Zak01 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? – aled Commented Mar 17 at 18:36
 |  Show 5 more comments

1 Answer 1

Reset to default 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
)
发布评论

评论列表(0)

  1. 暂无评论