使用Groovy将XML转换为JSON

5anewei6  于 2023-04-29  发布在  其他
关注(0)|答案(1)|浏览(203)

我正在尝试使用SAP CPI中的Groovy将XML转换为所需的JSON。使用SAP CPI提供的标准XML到JSON转换器,我没有得到想要的结果。我写了下面的groovy代码,它给了我JSON,除了数组名。

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

我不知道如何填充“值”标签之前,数组一样预期的输出。

bq9c1y66

bq9c1y661#

您可以将values中的元素转换为以Value为键的Maps。试着改变路线

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

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

编辑

现在我再看一遍,按!element."$it".children().size()过滤的方式可能会导致意外的行为。我不确定这是否是你真正想要的。如果你想要Value下的所有叶子,你可以试试

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

相关问题