Mule Dataweave 2如何将对象映射到对象的JSON数组

Mule Dataweave 2如何将对象映射到对象的JSON数组,mule,dataweave,Mule,Dataweave,有一个JSON对象,我需要将它映射到一个对象数组,但在多次尝试后无法获得正确的结构。如果脚本变得非常复杂并破坏可读性和易维护性,将此过程划分为多个脚本而不是一个dataweave 2脚本会更好吗 电流输出: { "batchId": "71f7a8534907940cb1b5", "status": "1", "products": [ { "materi

有一个JSON对象,我需要将它映射到一个对象数组,但在多次尝试后无法获得正确的结构。如果脚本变得非常复杂并破坏可读性和易维护性,将此过程划分为多个脚本而不是一个dataweave 2脚本会更好吗

电流输出:

{
  "batchId": "71f7a8534907940cb1b5",
  "status": "1",
  "products": [
    {
      "materialNumber": "9780429435942",
      "errorMessages": [
        "Failure",
        "Mistake"
      ],
      "materialNumber": "9780429435950",
      "errorMessages": [
        "Exception"
      ]
    }
  ]
}
期望输出:

{
  "batchId": "71f7a8534907940cb1b5",
  "status": "1",
  "products": [
    {
      "materialNumber": "9780429435942",
      "errorMessages": [
        "Failure",
        "Mistake"
      ]
    },
    {
      "materialNumber": "9780429435950",
      "errorMessages": [
        "Exception"
      ]
    }
  ]
}
DW2脚本:

%dw 2.0
output application/json
var failedProducts = vars.response.materials filterObject ((product) -> product.status == "1")
---
{
    batchId: vars.batchId,
    status: vars.overallStatus,
    products: [
        failedProducts mapObject (value,key,index) -> {
            materialNumber: value.materialNumber,
            errorMessages: value.messages.*item.*msgText
        }
    ]
}
来源数据:

<response>
    <overallStatus>1</overallStatus>
    <materials>
      <item>
        <status>0</status>
        <materialNumber>9781231231231</materialNumber>
        <messages>
          <item>
            <msgText>Success</msgText>
          </item>
        </messages>
      </item>
      <item>
        <status>1</status>
        <materialNumber>9780429435942</materialNumber>
        <messages>
          <item>
            <msgText>Failure</msgText>
          </item>
          <item>
            <msgText>Mistake</msgText>
          </item>
        </messages>
      </item>
      <item>
        <status>1</status>
        <materialNumber>9780429435950</materialNumber>
        <messages>
          <item>
            <msgText>Exception</msgText>
          </item>
        </messages>
      </item>
    </materials>
</response>

1.
0
9781231231231
成功
1.
9780429435942
失败
错误
1.
9780429435950
例外情况
以下代码(与您的代码不同)可为您提供所需的结果:

%dw 2.0
output application/json
var xml = '
<response>
    <overallStatus>1</overallStatus>
    <materials>
      <item>
        <status>0</status>
        <materialNumber>9781231231231</materialNumber>
        <messages>
          <item>
            <msgText>Success</msgText>
          </item>
        </messages>
      </item>
      <item>
        <status>1</status>
        <materialNumber>9780429435942</materialNumber>
        <messages>
          <item>
            <msgText>Failure</msgText>
          </item>
          <item>
            <msgText>Mistake</msgText>
          </item>
        </messages>
      </item>
      <item>
        <status>1</status>
        <materialNumber>9780429435950</materialNumber>
        <messages>
          <item>
            <msgText>Exception</msgText>
          </item>
        </messages>
      </item>
    </materials>
</response>
'
var data = read(xml,"application/xml")
var batchId = "71f7a8534907940cb1b5"
---
{
    batchId: batchId,
    status: data.response.overallStatus,
    products: 
        data.response.materials.*item filter ($.status as Number != 0)
        map {
            materialNumber: $.materialNumber,
            errorMessages: [$.messages.item]
        }
}
%dw 2.0
输出应用程序/json
var xml='1〕
1.
0
9781231231231
成功
1.
9780429435942
失败
错误
1.
9780429435950
例外情况
'
var data=read(xml,“应用程序/xml”)
var batchId=“71f7a8534907940cb1b5”
---
{
batchId:batchId,
状态:data.response.overallStatus,
产品:
data.response.materials.*项目筛选器($.status as Number!=0)
地图{
物料编号:$。物料编号,
errorMessages:[$.messages.item]
}
}

我确实使用了DW变量而不是
vars

您面临的问题是,XML本身不支持数组。因此,在使用dataweave读取XML时,您需要明确指出您希望将某个路径作为数组读取,这正是您在dataweave中编写
value.messages.*item.*msgText
时所做的。您只需要对“item”元素(您称之为products)执行相同的操作

这是您正在寻找的dataweave:

%dw 2.0
output application/json
var failedProducts = vars.response.materials.*item filter ((product) -> product.status == "1")
---
{
    batchId: vars.batchId,
    status: vars.overallStatus,
    products: failedProducts map (value) -> {
            materialNumber: value.materialNumber,
            errorMessages: value.messages.*item.*msgText
        }
 }

我自己尝试时缺少了一些值(例如变量),但是如果您将
errorMessages:value.messages.*item.*msgText
更改为
[errorMessages:value.messages.*item.*msgText[0]].
您可能会得到想要的结果。非常好,谢谢!正是我需要的。正如您所说,我的主要问题是过滤器不正确-缺少
*项
我想您不需要
*msgText
。它可能很简单。msgText cause
*item
已经处理好了。@Thinker-101是的,不需要它,但是为了将来更好的可读性,最好把它放在这里。只要看一下它,就可以清楚地看出它是一个数组。不过,这取决于你的喜好。
%dw 2.0
output application/json
var failedProducts = vars.response.materials filterObject ((value) -> value.status contains  "1")
---
{
    batchId: vars.batchId,
    status: vars.overallStatus,
    products: failedProducts.*item map (value) -> {
            materialNumber: value.materialNumber,
            errorMessages: value.messages.*item.msgText
        }
}