Search code examples
dataweavemulesoftmule4

How to populate an xml tag conditionally in DataWeave?


I want to iterate over this below tag:

      <pur:Schedule>
        <pur:StatusNumber>1</pur:StatusNumber>
        <pur:RequestDate>2023-02-22</pur:RequestDate>
        <pur:Action>CHANGE</pur:Action>
      </pur:Schedule>

I want to populate the above tag when the Mode is equal to CHANGE else if the Mode is equal to CANCEL skip the entire tag.

Input Payload

{"Order": {
    "Reason": "apple",
"Line": [
    {
"Quantity": 30,
"Date": "2023-02-22","Pricing": {
    "Amount": "11.34"},"Details": {
        "Number": "247"}},
         {
"Quantity": 12,
"Date": "2023-02-25","Pricing": {
    "Amount": "11.34"},"Details": {
        "Number": "247"}},
         {
"Quantity": 0,
"Date": "2023-02-21","Pricing": {
    "Amount": "11.34"},"Details": {
        "Number": "247"}}
        
        ]}}

Used Dataweave Script

%dw 2.0
output text/xml writeDeclaration=false
ns typ http://xmlns.oracle.com/apps/prc/po/editDocument/order/types/
ns pur http://xmlns.oracle.com/apps/prc/po/editDocument/order/
---
{typ#Product: {
    typ#Entry: {
        pur#OrderId: payload.Order.Line.Details.Number[0],
pur#OrderDescription: payload.Order.Reason,pur#EntryLine: payload.Order.Line map {
    pur#productNumber: $.Details.Line_Number,
pur#Qty: $.Ordered_Quantity,
pur#unit: $.Pricing.Amount ,
pur#status: if($.Quantity != 0) "Changed" else "",
pur#Mode: if($.Quantity == 0) "CANCEL" else "CHANGE",pur#Reason: if($.Quantity == 0) "Cancelled" else "",
(pur#Schedule: {
    pur#StatusNumber: "1",
    pur#RequestDate: $.Date,
    pur#Action: "CHANGE"})
    }}}}

Expected Output

<typ:Product xmlns:typ="http://xmlns.oracle.com/apps/prc/po/editDocument/order/types/">
  <typ:Entry>
    <pur:OrderId xmlns:pur="http://xmlns.oracle.com/apps/prc/po/editDocument/order/">247</pur:OrderId>
    <pur:OrderDescription xmlns:pur="http://xmlns.oracle.com/apps/prc/po/editDocument/order/">apple</pur:OrderDescription>
    <pur:EntryLine xmlns:pur="http://xmlns.oracle.com/apps/prc/po/editDocument/order/">
      <pur:productNumber/>
      <pur:Qty/>
      <pur:unit>11.34</pur:unit>
      <pur:status>Changed</pur:status>
      <pur:Mode>CHANGE</pur:Mode>
      <pur:Reason/>
      <pur:Schedule>
        <pur:StatusNumber>1</pur:StatusNumber>
        <pur:RequestDate>2023-02-22</pur:RequestDate>
        <pur:Action>CHANGE</pur:Action>
      </pur:Schedule>
    </pur:EntryLine>
    <pur:EntryLine xmlns:pur="http://xmlns.oracle.com/apps/prc/po/editDocument/order/">
      <pur:productNumber/>
      <pur:Qty/>
      <pur:unit>11.34</pur:unit>
      <pur:status>Changed</pur:status>
      <pur:Mode>CHANGE</pur:Mode>
      <pur:Reason/>
      <pur:Schedule>
        <pur:StatusNumber>1</pur:StatusNumber>
        <pur:RequestDate>2023-02-25</pur:RequestDate>
        <pur:Action>CHANGE</pur:Action>
      </pur:Schedule>
    </pur:EntryLine>
    <pur:EntryLine xmlns:pur="http://xmlns.oracle.com/apps/prc/po/editDocument/order/">
      <pur:productNumber/>
      <pur:Qty/>
      <pur:unit>11.34</pur:unit>
      <pur:status/>
      <pur:Mode>CANCEL</pur:Mode>
      <pur:Reason>Cancelled</pur:Reason>
    </pur:EntryLine>
  </typ:Entry>
</typ:Product>


Solution

  • You can add a conditional to the section of the script that generates that key. Note that the output of the script can not be used as part of the script. Avoid that way of expressing the problem. Instead think on terms of how the input generates the output. I reused the condition that generates the element Mode.

            (
              pur#Schedule: {
                pur#StatusNumber: "1",
                pur#RequestDate: $.Date,
                pur#Action: "CHANGE"
              }
            ) if ($.Quantity != 0)