You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:47:04