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

在SAP CPI中使用Groovy实现XML转JSON的格式调整问题

SAP CPI中Groovy XML转指定JSON格式的调整方案

问题场景

在SAP CPI中使用标准XML转JSON转换器无法得到预期格式,编写Groovy代码后,生成的JSON里Rows数组的元素是直接的数组,需要调整为每个元素是包含Value键的对象。

原Groovy代码

def xml = """<Rows>
    <Values>
    <Value>
        <Name>DummyTest_1</Name>
        <Site.Value>3</Site.Value>
        <Description>Dummy PN For Test 1</Description>
        <Type.Value>N</Type.Value>
        <BuyerCode.Value/>,
      <PlannerCode.Value/>,
      <PlannerCode.Description/>,
      <ABCCode.Value>Default</ABCCode.Value>
        <UnitOfMeasure.Value>LB</UnitOfMeasure.Value>
        <SafetyStockQty>1</SafetyStockQty>
        <StdUnitCost>10</StdUnitCost>
        <AverageSellingPrice>15</AverageSellingPrice>
        <ProductFamily.Value/>
        <ProductGroup1>CHC</ProductGroup1>
        <IncrementalRule.Value>Default</IncrementalRule.Value>
        <MUEPoolNettingType.Value>Ignore</MUEPoolNettingType.Value>
        <PlanningCalendars.Value>Default</PlanningCalendars.Value>
        <SourceRule.Value>Default</SourceRule.Value>
    </Value>
    <Value>
        <Name>DummyTest_2</Name>
        <Site.Value>4</Site.Value>
        <Description>Dummy PN For Test 2</Description>
        <Type.Value>H</Type.Value>
        <BuyerCode.Value/>,
      <PlannerCode.Value/>,
      <PlannerCode.Description/>,
      <ABCCode.Value>Default2</ABCCode.Value>
        <UnitOfMeasure.Value>BL</UnitOfMeasure.Value>
        <SafetyStockQty>2</SafetyStockQty>
        <StdUnitCost>20</StdUnitCost>
        <AverageSellingPrice>16</AverageSellingPrice>
        <ProductFamily.Value/>
        <ProductGroup1>CHC</ProductGroup1>
        <IncrementalRule.Value>Default</IncrementalRule.Value>
        <MUEPoolNettingType.Value>Ignore</MUEPoolNettingType.Value>
        <PlanningCalendars.Value>Default</PlanningCalendars.Value>
        <SourceRule.Value>Default</SourceRule.Value>
    </Value>
    </Values>
</Rows>"""

def parsed = new XmlSlurper().parseText(xml)

def values = ['Rows' :  parsed.'**'.findAll{it.name() == 'Value'}.collect{element -> element.children().breadthFirst()*.name().findAll { !element."$it".children().size() }.collect{element."$it".text()}}]
def fields = ['Fields' :  parsed.'**'.find{it.name() == 'Value'}.collect{element -> element.children().breadthFirst()*.name()
             .findAll { !element."$it".children().size() }
           .collect{element."$it".name()}}]

fields += values
println new groovy.json.JsonBuilder(fields).toPrettyString()

当前输出

{
    "Fields": [
        [
            "Name",
            "Site.Value",
            "Description",
            "Type.Value",
            "BuyerCode.Value",
            "PlannerCode.Value",
            "PlannerCode.Description",
            "ABCCode.Value",
            "UnitOfMeasure.Value",
            "SafetyStockQty",
            "StdUnitCost",
            "AverageSellingPrice",
            "ProductFamily.Value",
            "ProductGroup1",
            "IncrementalRule.Value",
            "MUEPoolNettingType.Value",
            "PlanningCalendars.Value",
            "SourceRule.Value"
        ]
    ],
    "Rows": [
        [
            "DummyTest_1",
            "3",
            "Dummy PN For Test 1",
            "N",
            "",
            "",
            "",
            "Default",
            "LB",
            "1",
            "10",
            "15",
            "",
            "CHC",
            "Default",
            "Ignore",
            "Default",
            "Default"
        ],
        [
            "DummyTest_2",
            "4",
            "Dummy PN For Test 2",
            "H",
            "",
            "",
            "",
            "Default2",
            "BL",
            "2",
            "20",
            "16",
            "",
            "CHC",
            "Default",
            "Ignore",
            "Default",
            "Default"
        ]
    ]
}

预期输出

{
    "Fields": [
        [
            "Name",
            "Site.Value",
            "Description",
            "Type.Value",
            "BuyerCode.Value",
            "PlannerCode.Value",
            "PlannerCode.Description",
            "ABCCode.Value",
            "UnitOfMeasure.Value",
            "SafetyStockQty",
            "StdUnitCost",
            "AverageSellingPrice",
            "ProductFamily.Value",
            "ProductGroup1",
            "IncrementalRule.Value",
            "MUEPoolNettingType.Value",
            "PlanningCalendars.Value",
            "SourceRule.Value"
        ]
    ],
    "Rows": [
     {
        "Value":[
            "DummyTest_1",
            "3",
            "Dummy PN For Test 1",
            "N",
            "",
            "",
            "",
            "Default",
            "LB",
            "1",
            "10",
            "15",
            "",
            "CHC",
            "Default",
            "Ignore",
            "Default",
            "Default"
        ]
        },
        {
          "Value":[
            "DummyTest_2",
            "4",
            "Dummy PN For Test 2",
            "H",
            "",
            "",
            "",
            "Default2",
            "BL",
            "2",
            "20",
            "16",
            "",
            "CHC",
            "Default",
            "Ignore",
            "Default",
            "Default"
        ]
        }
    ]
}

修改方案

只需调整values变量的生成逻辑,将每个值数组包装成包含Value键的Map对象即可:

修改后的Groovy代码

def xml = """<Rows>
    <Values>
    <Value>
        <Name>DummyTest_1</Name>
        <Site.Value>3</Site.Value>
        <Description>Dummy PN For Test 1</Description>
        <Type.Value>N</Type.Value>
        <BuyerCode.Value/>,
      <PlannerCode.Value/>,
      <PlannerCode.Description/>,
      <ABCCode.Value>Default</ABCCode.Value>
        <UnitOfMeasure.Value>LB</UnitOfMeasure.Value>
        <SafetyStockQty>1</SafetyStockQty>
        <StdUnitCost>10</StdUnitCost>
        <AverageSellingPrice>15</AverageSellingPrice>
        <ProductFamily.Value/>
        <ProductGroup1>CHC</ProductGroup1>
        <IncrementalRule.Value>Default</IncrementalRule.Value>
        <MUEPoolNettingType.Value>Ignore</MUEPoolNettingType.Value>
        <PlanningCalendars.Value>Default</PlanningCalendars.Value>
        <SourceRule.Value>Default</SourceRule.Value>
    </Value>
    <Value>
        <Name>DummyTest_2</Name>
        <Site.Value>4</Site.Value>
        <Description>Dummy PN For Test 2</Description>
        <Type.Value>H</Type.Value>
        <BuyerCode.Value/>,
      <PlannerCode.Value/>,
      <PlannerCode.Description/>,
      <ABCCode.Value>Default2</ABCCode.Value>
        <UnitOfMeasure.Value>BL</UnitOfMeasure.Value>
        <SafetyStockQty>2</SafetyStockQty>
        <StdUnitCost>20</StdUnitCost>
        <AverageSellingPrice>16</AverageSellingPrice>
        <ProductFamily.Value/>
        <ProductGroup1>CHC</ProductGroup1>
        <IncrementalRule.Value>Default</IncrementalRule.Value>
        <MUEPoolNettingType.Value>Ignore</MUEPoolNettingType.Value>
        <PlanningCalendars.Value>Default</PlanningCalendars.Value>
        <SourceRule.Value>Default</SourceRule.Value>
    </Value>
    </Values>
</Rows>"""

def parsed = new XmlSlurper().parseText(xml)

// 关键修改:将每个值数组包装成["Value": 数组]的Map
def values = ['Rows' :  parsed.'**'.findAll{it.name() == 'Value'}.collect{element -> 
    def valueList = element.children().breadthFirst()*.name().findAll { !element."$it".children().size() }.collect{element."$it".text()}
    [Value: valueList]
}]
def fields = ['Fields' :  parsed.'**'.find{it.name() == 'Value'}.collect{element -> element.children().breadthFirst()*.name()
             .findAll { !element."$it".children().size() }
           .collect{element."$it".name()}}]

fields += values
println new groovy.json.JsonBuilder(fields).toPrettyString()

说明

原代码中collect直接返回值数组,修改后在collect闭包里先生成值数组,再返回[Value: valueList]格式的Map,这样Rows数组的每个元素就变成了包含Value键的对象,完全匹配预期格式。


内容的提问来源于stack exchange,提问作者Kaushik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:44:54