DataWeave — добавить дополнительный элемент после итерации, используемой для списка

Я пытаюсь создать следующий 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 выдает мне ошибку из-за того, что я смешал массив с объектом.

%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"
            }
        }
    }
}

Возможно ли сделать то, что я пытаюсь?

Сценарий, которым вы поделились, неполный. Пожалуйста, отредактируйте вопрос, чтобы добавить полный сценарий, который можно использовать для воспроизведения проблемы. Также включите ввод.

aled 14.07.2024 17:41

@aled добавил полный пример, извините!

mripoll 14.07.2024 18:55

Если есть ошибки, добавьте к вопросу полный текст. Также полный ввод для воспроизведения. Прочтите, как написать минимально воспроизводимый пример .

aled 14.07.2024 19:15
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Мне не удалось воспроизвести проблему, возможно, потому, что у вас недостаточно информации для полного воспроизведения. Однако, глядя на желаемый результат, вы можете использовать функцию reduce() для преобразования внутреннего массива в объект. Это позволит достичь желаемого результата.

%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"
                    }
        }
    }
}

Я использовал эти фиктивные данные в качестве входных данных и соответственно изменил выражение для MeterReading:

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

Выход:

<?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>

Большое спасибо за помощь. Я попробовал решение, к сожалению, отображается ошибка типа: Невозможно вызвать: reduce с аргументами: (Array<{|ns0#Readings...2011/MeterReadings , ($, $$) -> ?). Причины: - Повторяющееся поле: Readings не поддерживается: `{|ns0#Readings: {|ns...2011/MeterReadings |- From: сокращение<T>(items: Array<T>, обратный вызов: (item: T , аккумулятор: Т) -> Т) -> Т | Нулевой

mripoll 14.07.2024 18:54

Кстати, я генерирую данные из компонента Java, поэтому, возможно, типы более запутанны.

mripoll 14.07.2024 18:59

Это сложно воспроизвести, поскольку вы не предоставляете фактические данные, однако я считаю, что это связано с автоматической инициализацией аккумулятора в функции уменьшения(). Я обновил свой пример явной инициализацией пустого объекта. Попробуйте это изменение и дайте мне знать.

aled 14.07.2024 20:04

Большое спасибо! Нашел альтернативу, которая тоже работает. Извините, что не могу предоставить полный пример, некоторая логика создается с использованием автоматически создаваемых классов и специального компонента Java.

mripoll 14.07.2024 21:06

Вы можете уменьшить проблему, чтобы избежать этой зависимости в вопросе. В этом и заключается идея минимального воспроизводимого примера .

aled 14.07.2024 22:42

Мое решение состояло в том, чтобы использовать объект для определения иерархии и использовать массив для списка показаний:

%dw 2.0
output application/xml
ns met http://iec.ch/TC57/2011/MeterReadingsMessage
ns mes http://iec.ch/TC57/2011/schema/message
ns met1 http://iec.ch/TC57/2011/MeterReadings#

var meterReadings = payload.MeterReadings
var meterReading = meterReadings.MeterReading
var readings = meterReading.readings[0]

//var requestData = read(vars.queryOperation.RequestData, "application/json")

---
met#CreatedMeterReadings: {
    met#Header: {
        mes#Verb: "reply",
        mes#Noun: "MeterReadings"
    },
    met#Payload: {
        met1#MeterReadings: {
            met1#MeterReading: {
                met1#Readings: readings map ((reading) -> {
                    met1#reportedDateTime: reading.reportedDateTime,
                    met1#timeStamp: reading.timeStamp,
                    met1#value: reading.value,
                    met1#ReadingType @("ref": reading.ReadingType.ref): {}
                }),
                met1#UsagePoint: {
                    met1#mRID: "usagePoint"
                }
            }
        }
    }
}

Другие вопросы по теме