XML解析以使用DataWeave 2转换JSON

问题描述

我试图使用dataweave 2递归解析XML以创建JSON数组,但是我无法做到。

我的输入XML如下-

ax.imshow(img,cmap='gray',vmin=0,vmax=1)

我想创建所有BOM表(无层次结构的平面结构)的JSON数组,其parentId作为父BOM的RecId,如下所示-

输出-

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="android.aspx.cs" Inherits="finalproject.android" %>

<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
    <style type="text/css">
.style1
{
    width:900px;
}
.style2
{
    width:633px;
    text-align:left;
}
.style4
{
    width:185px;
    text-align:center;
}
</style>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <asp:DataList ID="DataList1" runat="server" DataKeyField="modelid" 
        style="text-align: center; color: #333333;" RepeatColumns="3"
        Width="283px" DataSourceID="sqlDataSource2" CellPadding="3" 
    BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px" 
    CellSpacing="1" >
        <FooterStyle BackColor="#C6C3C6" ForeColor="Black" />
        <HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" />
        <ItemStyle BackColor="#DEDFDE" ForeColor="Black" />
        <ItemTemplate>
            <br />
            <div align="left"></div>
            <table cellspacing="1" class="style4" style="border:1px ridge #9900FF">
                <tr>
                    <td style="border-bottom-style:ridge; border-width: 1px; border-color: #000000">
                        <asp:Label ID="Label1" runat="server" Text="<%# Eval('brand') %>"></asp:Label>
                    </td>
                </tr>
                <tr>
                    <td>
                        <asp:ImageButton ID="ImageButton1" runat="server" Height="252px"
                            ImageUrl="<%# Image %>" style="margin-left: 0px" />
                    </td>
                </tr>
                <tr>
                    <td>
                        ModelID<asp:Label ID="Label2" runat="server" Text="<%# Eval('modelid') %>"></asp:Label>
                    </td>
                </tr>
                <tr>
                    <td>
                        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" 
                            CommandArgument="<%# Bind('ModelID') %>" Text="Add to Cart" Width="100%" BorderColor="Black" BorderStyle="Inset" BorderWidth="1px" />
                    </td>
                </tr>
            </table>
            <br />
        </ItemTemplate>
        <SelectedItemStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" />
    </asp:DataList>
    <asp:sqlDataSource ID="sqlDataSource2" runat="server" 
    ConnectionString="<%$ ConnectionStrings:VISHConnectionString2 %>" 
    SelectCommand="SELECT [Image],[modelid],[brand] FROM [adddetails]">
</asp:sqlDataSource>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <table align="left" class="style2">
                <tr>
                    <td>
                        <asp:Label ID="Label3" runat="server" style="color: #333333"></asp:Label>
                    </td>
                </tr>
                <tr>
                    <td>
                        &nbsp;</td>
                </tr>
                <tr>
                    <td>
                        &nbsp;</td>
                </tr>
                <tr>
                    <td>
                        &nbsp;</td>
                </tr>
            </table>
        </ContentTemplate>
    </asp:UpdatePanel>
</asp:Content>

映射规则-

  1. id:BOM-> RecId
  2. productId:BOM-> ItemId
  3. parentId:父BOM的RecId

与建议答案的区别在于,我需要使用BOM表而不是BOM表的直接Recid来设置parentid。

解决方法

在给定输入的情况下,您的输出似乎还是错误的(例如,产品ID 96AR060W不在输入xml中)。要回答您的问题,而不是收集所有BOM表对象,您可以遍历单个BOM表对象以保存父ID并创建可以递归调用的函数。请参见下面的数据编织:

%dw 2.0
output application/json

fun parseBOM(bomData,parentId) = 
    if (bomData.BOMTable.BOM?) 
        [{
            id: bomData.RecId,productId: bomData.ItemId,parentId: parentId  
        }] ++ (bomData.BOMTable.*BOM flatMap parseBOM($,bomData.RecId))
    else {
        id: bomData.RecId,parentId: parentId
    }

---
using (firstBOMTable =  payload.MessageParts.BillsOfMaterials.BOMVersion.BOMTable)
firstBOMTable.*BOM flatMap parseBOM($,null)

给出您的输入xml,结果将

[
  {
    "id": "5637307757","productId": "9650092","parentId": null
  },{
    "id": "5637307799","productId": "9650079","parentId": "5637307757"
  },{
    "id": "5637307800","productId": "9644919T",{
    "id": "5637307801","productId": "9644920",{
    "id": "5637307802","productId": "9700720Z",{
    "id": "5637333626","productId": "9700595","parentId": "5637307802"
  },{
    "id": "5637333627","productId": "9608224Z",{
    "id": "5637307803","productId": "9683336L",{
    "id": "5637309242","productId": "G211249","parentId": "5637307803"
  },{
    "id": "5637309243","productId": "G25583961_24",{
    "id": "5637307758","productId": "9608221Z",{
    "id": "5637307759","productId": "9700624Y",{
    "id": "5637333624","productId": "9644921","parentId": "5637307759"
  },{
    "id": "5637307760","productId": "9700815","parentId": null
  }
]

该函数的作用是,如果所提供的对象(bomData)包含BOMTable.BOM,则创建所需的对象,并使用其下的所有BOM对象再次调用同一函数。该函数也接受parentId作为参数来保存它。