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

问题描述

一个 JSON 对象,我需要将其映射到一个对象数组,但多次尝试后无法立即获得结构。如果脚本变得非常复杂,破坏了可读性和易维护性,将这个过程分成多个脚本而不是一个 dataweave 2 脚本会更好吗?

当前输出

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

所需的输出

{
  "batchId": "71f7a8534907940cb1b5","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>

解决方法

以下代码(与您的不同)可为您提供所需的结果:

%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 变量而不是您拥有的 vars

,

您面临的问题是因为 XML 本机不支持数组。因此,在使用 dataweave 读取 XML 时,您需要明确提及您希望将某个路径作为数组读取,这正是您在 dataweave 中写入 value.messages.*item.*msgText 时所做的。你只需要对“item”元素(你称之为产品)做同样的事情。

这是您要查找的数据编织:

%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
        }
 }
,
%dw 2.0
output application/json
var failedProducts = vars.response.materials filterObject ((value) -> value.status contains  "1")
---
{
    batchId: vars.batchId,products: failedProducts.*item map (value) -> {
            materialNumber: value.materialNumber,errorMessages: value.messages.*item.msgText
        }
}