muledataweavemule4

DataWeave - Add additional item after iteration used for list


I'm trying to create the following XML:

<ns10:Payload>
   <ns6:MeterReadings>
      <ns6:MeterReading>
         <ns6:Readings>
            <ns6:reportedDateTime>2024-06-02T23:15:11.09+02:00</ns6:reportedDateTime>
            <ns6:timeStamp>2024-06-02T23:14:39+02:00</ns6:timeStamp>
            <ns6:value>0.234</ns6:value>
            <ns6:ReadingType ref="0.0.0.6.0.1.54.0.0.0.0.0.0.0.128.3.29.0"/>
         </ns6:Readings>
         <ns6:Readings>
            <ns6:reportedDateTime>2024-06-02T23:15:11.09+02:00</ns6:reportedDateTime>
            <ns6:timeStamp>2024-06-02T23:14:39+02:00</ns6:timeStamp>
            <ns6:value>0.233</ns6:value>
            <ns6:ReadingType ref="0.0.0.6.0.1.54.0.0.0.0.0.0.0.64.3.29.0"/>
         </ns6:Readings>
         <ns6:UsagePoint>
            <ns6:mRID>ES00TRAFGISS03268T120F</ns6:mRID>
         </ns6:UsagePoint>
      </ns6:MeterReading>
   </ns6:MeterReadings>
</ns10:Payload>

I've used the ++ operation to add the element UsagePoint at the end of the list but Mule gives me an error due to me mixing an array with an object.

%dw 2.0
output application/xml
ns ns0 http://iec.ch/TC57/2011/MeterReadingsMessage
ns ns01 http://iec.ch/TC57/2011/schema/message
ns ns02 http://iec.ch/TC57/2011/MeterReadings

var meterReadings = payload.MeterReadings
var meterReading = meterReadings.MeterReading
var readings = meterReading.readings[0] as Array<T>

---
ns0#CreatedMeterReadings: {
    ns0#Header: {
        ns01#Verb: "reply",
        ns01#Noun: "MeterReadings"
    },
    ns0#Payload: {
        ns02#MeterReadings: {
            ns02#MeterReading: readings map ((reading) -> {
                ns02#Readings: {
                    ns02#reportedDateTime: reading.reportedDateTime,
                    ns02#timeStamp: reading.timeStamp,
                    ns02#value: reading.value,
                    ns02#ReadingType: reading.ReadingType
                } 
            })
            reduce ($$ ++ $) 
            ++ ns02#UsagePoint: {
                ns02#mRID: "example"
            }
        }
    }
}

Is it possible to do what I'm trying?


Solution

  • I could not reproduce the issue, probably because you haven't share enough for a full reproduction. However looking at the desired output, you can use the reduce() function to convert the inner array to an object. That will achieve the desired output.

    %dw 2.0
    output application/xml
    ns ns0 http://something
    ns ns02 http://somethingelse
    ---
    ns0#CreatedMeterReadings: {
        ns0#Payload: {
            ns02#MeterReadings: {
                ns02#MeterReading: payload map ((reading) -> {
                        ns02#Readings: {
                            ns02#reportedDateTime: reading.reportedDateTime,
                            ns02#timeStamp: reading.timeStamp,
                            ns02#value: reading.value,
                            ns02#ReadingType: reading.ReadingType
                        } 
                    }) 
                        reduce ((item, accumulator={}) -> accumulator ++ item)  
                        ++ ns02#UsagePoint: {
                            ns02#mRID: "example"
                        }
            }
        }
    }
    

    I used this dummy data as input an changed the expression for MeterReading accordingly:

    [
        {
            "reportedDateTime": 123,
            "timeStamp": 1,
            "value": 111,
            "ReadingType": "x"
        },    
        {
            "reportedDateTime": 321,
            "timeStamp": 2,
            "value": 222,
            "ReadingType": "y"
        }
    ]
    

    Output:

    <?xml version='1.0' encoding='UTF-8'?>
    <ns0:CreatedMeterReadings xmlns:ns0="http://something">
      <ns0:Payload>
        <ns02:MeterReadings xmlns:ns02="http://somethingelse">
          <ns02:MeterReading>
            <ns02:Readings>
              <ns02:reportedDateTime>123</ns02:reportedDateTime>
              <ns02:timeStamp>1</ns02:timeStamp>
              <ns02:value>111</ns02:value>
              <ns02:ReadingType>x</ns02:ReadingType>
            </ns02:Readings>
            <ns02:Readings>
              <ns02:reportedDateTime>321</ns02:reportedDateTime>
              <ns02:timeStamp>2</ns02:timeStamp>
              <ns02:value>222</ns02:value>
              <ns02:ReadingType>y</ns02:ReadingType>
            </ns02:Readings>
            <ns02:UsagePoint>
              <ns02:mRID>example</ns02:mRID>
            </ns02:UsagePoint>
          </ns02:MeterReading>
        </ns02:MeterReadings>
      </ns0:Payload>
    </ns0:CreatedMeterReadings>