DataWeave技术咨询:迭代列表后添加UsagePoint元素报错如何解决
问题:如何在DataWeave中生成包含多个Readings和UsagePoint的XML结构?
我想要生成如下结构的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>
我尝试使用++操作符在列表末尾添加UsagePoint元素,但Mule报错提示数组与对象类型不兼容。我的DataWeave代码如下:
%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" } } } }
请问是否可以实现我想要的效果?如果可以,该如何修改代码?
解决方案
可以实现,问题根源是你试图直接将对象类型的UsagePoint与reduce后的数组拼接,导致类型不兼容。正确的做法是把UsagePoint包装成数组元素,再和Readings数组合并,XML会自动将数组中的每个对象渲染为同级子元素。
修改后的DataWeave代码:
%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 } }) // 将UsagePoint包装为单元素数组,再和Readings数组合并 ++ [{ ns02#UsagePoint: { ns02#mRID: "ES00TRAFGISS03268T120F" } }]) } } }
关键修改说明:
- 移除冗余的
reduce操作:map本身会返回数组,无需额外用reduce拼接。 - 把
UsagePoint对象放入单元素数组中,确保++两侧都是数组类型,解决类型不兼容问题。 - XML输出时,数组内的每个对象会自动成为
ns02#MeterReading的同级子元素,完全匹配目标结构。
内容的提问来源于stack exchange,提问作者mripoll
相关产品推荐
相关产品推荐

