具有多个 LineItems 的 Xml 到 Json

问题描述 投票:0回答:1

我正在尝试将 xml 转换为 json,但在 xml 到 json 转换期间未形成多个行项目。我们总是在 xml 消息中包含与 'vpoItemList' 、 'vpoShipDtlDtoGroupList' 和 'vpoShipDtlCsGroupList' 相同名称的单个或多个 Lineitem。

请求检查代码以获取json文件中的所有lineitem作为预期的json文件。收到错误消息:

xml-to-json:重复的键值 {vpoItemList}。

输入xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<ns0:PO_Message
    xmlns:ns0="http://test.com/Test">
    <domainId>MAIL</domainId>
    <hubDomainId>MAIL</hubDomainId>
    <isForReference>false</isForReference>
    <status>releasedToVendor</status>
    <docStatus>active</docStatus>
    <editingStatus>confirmed</editingStatus>
    <vpoNo>28288</vpoNo>
    <vpoDate>2021-02-23</vpoDate>
    <instructions>METAL-No Size:1360600001-Article Number</instructions>
    <businessRefNo>28118</businessRefNo>
    <totalItems>1</totalItems>
    <totalQty>160</totalQty>
    <season>
        <code>F21</code>
    </season>
    <custId>
        <refNo>C000001</refNo>
    </custId>
    <vendorId>
        <vendorCode>41843</vendorCode>
    </vendorId>
    <headerFactory>
        <refNo>F000026</refNo>
        <factCode>900088</factCode>
    </headerFactory>
    <vpoItemList>
        <itemNo>19979-2021-0002-41843</itemNo>
        <itemName>Base Camp 6 Footprint</itemName>
        <customerItemNo>19979</customerItemNo>
        <lotNo>1</lotNo>
        <itemDesc>Base Camp 6 Footprint</itemDesc>
        <shipQty>160</shipQty>
        <planedQty>160</planedQty>
        <qtyPerExportCarton>160</qtyPerExportCarton>
        <qtyPerInnerCarton>160</qtyPerInnerCarton>
        <factCode>900088</factCode>
        <refNo>19979-2021-0002-41843-1</refNo>
        <uom>
            <code>PCS</code>
        </uom>
        <brand>
            <code>MAIL Co-op</code>
        </brand>
        <itemId>
            <itemNo>19979-2021-0002-41843</itemNo>
        </itemId>
        <portOfLoading>
            <code>DLC Dalian</code>
        </portOfLoading>
        <vpoItemCsList>
            <itemLotNo>19979-2021-0002-41843-Lot1</itemLotNo>
            <vpoItemColorRef>METAL</vpoItemColorRef>
            <vpoItemColorId>
                <refNo>METAL</refNo>
                <shortName>METAL</shortName>
            </vpoItemColorId>
            <vpoItemSizeId>
                <refNo>No Size</refNo>
                <displayName>No Size</displayName>
            </vpoItemSizeId>
            <itemId>
                <itemNo>19979-2021-0002-41843</itemNo>
            </itemId>
            <lotNo>1</lotNo>
        </vpoItemCsList>
        <factId>
            <factCode>900088</factCode>
        </factId>
    </vpoItemList>
    <vpoItemList>
        <itemNo>22825-2021-0001-43095</itemNo>
        <itemName>Flash 22 Member Exclusive</itemName>
        <customerItemNo>22825</customerItemNo>
        <lotNo>1</lotNo>
        <itemDesc>Flash 22 Member Exclusive</itemDesc>
        <shipQty>160</shipQty>
        <planedQty>160</planedQty>
        <qtyPerExportCarton>160</qtyPerExportCarton>
        <qtyPerInnerCarton>160</qtyPerInnerCarton>
        <factCode>900088</factCode>
        <refNo>22825-2021-0001-43095-1</refNo>
        <uom>
            <code>PCS</code>
        </uom>
        <brand>
            <code>MAIL Co-op</code>
        </brand>
        <itemId>
            <itemNo>22825-2021-0001-43095</itemNo>
        </itemId>
        <portOfLoading>
            <code>DLC Dalian</code>
        </portOfLoading>
        <vpoItemCsList>
            <itemLotNo>22825-2021-0001-43095-Lot1</itemLotNo>
            <vpoItemColorRef>UNDYED</vpoItemColorRef>
            <vpoItemColorId>
                <refNo>UNDYED</refNo>
                <shortName>UNDYED</shortName>
            </vpoItemColorId>
            <vpoItemSizeRef>One Size</vpoItemSizeRef>
            <vpoItemSizeId>
                <refNo>One Size</refNo>
                <displayName>One Size</displayName>
                <sizeUniqueKey>SIZE1</sizeUniqueKey>
            </vpoItemSizeId>
            <itemId>
                <itemNo>22825-2021-0001-43095</itemNo>
            </itemId>
            <lotNo>1</lotNo>
        </vpoItemCsList>
        <factId>
            <factCode>900088</factCode>
        </factId>
    </vpoItemList>
    <vpoShipDtlDtoGroupList>
        <qty>160</qty>
        <refNo>00001/19979-2021-0002-41843-1</refNo>
        <vpoItemRef>19979-2021-0002-41843-1</vpoItemRef>
        <vpoItemId>
            <itemId>
                <itemNo>19979-2021-0002-41843</itemNo>
            </itemId>
        </vpoItemId>
        <vpoShipRef>00001</vpoShipRef>
        <vpoShipId>
            <shipmentNo>00001</shipmentNo>
            <originalShipmentDate>2021-08-17</originalShipmentDate>
            <shipmentDate>2021-08-23</shipmentDate>
            <originalInDcDate>2021-09-15</originalInDcDate>
            <inDcDate>2021-09-15</inDcDate>
            <refNo>00001/19979-2021-0002-41843-1</refNo>
            <shipMode>
                <code>3</code>
            </shipMode>
            <finalDestination>
                <code>0001</code>
            </finalDestination>
            <portOfLoading>
                <code>DLC Dalian</code>
            </portOfLoading>
        </vpoShipId>
        <shipMode>
            <code>3</code>
        </shipMode>
        <portOfLoading>
            <code>DLC Dalian</code>
        </portOfLoading>
    </vpoShipDtlDtoGroupList>
    <vpoShipDtlDtoGroupList>
        <qty>630</qty>
        <refNo>00001/22825-2021-0001-43095-1</refNo>
        <vpoItemRef>22825-2021-0001-43095-1</vpoItemRef>
        <vpoItemId>
            <itemId>
                <itemNo>22825-2021-0001-43095</itemNo>
            </itemId>
        </vpoItemId>
        <vpoShipRef>00001</vpoShipRef>
        <vpoShipId>
            <shipmentNo>00001</shipmentNo>
            <originalShipmentDate>2021-08-17</originalShipmentDate>
            <shipmentDate>2021-08-23</shipmentDate>
            <originalInDcDate>2021-09-15</originalInDcDate>
            <inDcDate>2021-09-15</inDcDate>
            <refNo>00001/19979-2021-0002-41843-1</refNo>
            <shipMode>
                <code>3</code>
            </shipMode>
            <finalDestination>
                <code>0001</code>
            </finalDestination>
            <portOfLoading>
                <code>DLC Dalian</code>
            </portOfLoading>
        </vpoShipId>
        <shipMode>
            <code>3</code>
        </shipMode>
        <portOfLoading>
            <code>DLC Dalian</code>
        </portOfLoading>
    </vpoShipDtlDtoGroupList>
    <vpoShipDtlCsGroupList>
        <itemLotNo>19979-2021-0002-41843-Lot1</itemLotNo>
        <shipmentNo>00001</shipmentNo>
        <colorSizeQty>160</colorSizeQty>
        <refNo>00001/19979-2021-0002-41843-1/METAL/No Size</refNo>
        <vpoItemRef>19979-2021-0002-41843-1</vpoItemRef>
        <vpoItemId>
            <itemId>
                <itemNo>19979-2021-0002-41843</itemNo>
            </itemId>
        </vpoItemId>
        <vpoShipRef>00001/19979-2021-0002-41843-1</vpoShipRef>
        <vpoItemColorRef>METAL</vpoItemColorRef>
        <vpoItemSizeRef>No Size</vpoItemSizeRef>
        <vpoShipDtlColorRef>1</vpoShipDtlColorRef>
        <vpoShipDtlSizeRef>1</vpoShipDtlSizeRef>
    </vpoShipDtlCsGroupList>
    <vpoShipDtlCsGroupList>
        <itemLotNo>22825-2021-0001-43095-Lot1</itemLotNo>
        <shipmentNo>00001</shipmentNo>
        <colorSizeQty>630</colorSizeQty>
        <refNo>00001/22825-2021-0001-43095-1/UNDYED/One Size</refNo>
        <vpoItemRef>22825-2021-0001-43095-1</vpoItemRef>
        <itemSizeId>035ae556951b413588cb935fe8abe89e</itemSizeId>
        <itemColorId>92bdbbe775cd470dbfaba3b58597f0a8</itemColorId>
        <itemColor />
        <vpoItemId>
            <itemId>
                <itemNo>22825-2021-0001-43095</itemNo>
            </itemId>
        </vpoItemId>
        <vpoShipRef>00001/22825-2021-0001-43095-1</vpoShipRef>
        <vpoItemColorRef>UNDYED</vpoItemColorRef>
        <vpoItemSizeRef>One Size</vpoItemSizeRef>
        <vpoShipDtlColorRef>1</vpoShipDtlColorRef>
        <vpoShipDtlSizeRef>1</vpoShipDtlSizeRef>
    </vpoShipDtlCsGroupList>
</ns0:PO_Message>

XSLT 代码:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns="http://www.w3.org/2005/xpath-functions"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <xsl:output method="text"/>

  <xsl:template match="/*" priority="5">
    <xsl:variable name="json-xml">
      <map>
        <xsl:apply-templates/>
      </map>        
    </xsl:variable>
    <xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
  </xsl:template>
  
  <xsl:template match="*[not(*)]">
    <string key="{local-name()}">{.}</string>
  </xsl:template>
  
  <xsl:template match="*[(*) and . castable as xs:double]">
    <number key="{local-name()}">{.}</number>
  </xsl:template>
  
  <xsl:template match="*[* and not(*[6])]">
    <map key="{local-name()}">
        <xsl:apply-templates/>
    </map>
  </xsl:template>
  
  <xsl:template match="*[* and *[6]]">
    <array key="{local-name()}">
        <map>
          <xsl:apply-templates/>
        </map>
    </array>
  </xsl:template>

  <xsl:template match="vpoShipDtlDtoGroupList/vpoShipId">
      <map key="{local-name()}">
          <xsl:apply-templates/>
      </map>
  </xsl:template>
  <xsl:template match="vpoShipDtlDtoGroupList | vpoShipDtlCsGroupList" priority="20">
    <array key="{local-name()}">
        <array>
          <map>
            <xsl:apply-templates/>
          </map>          
        </array>
    </array>
  </xsl:template>

</xsl:stylesheet>

预期的 json 文件:

{
    "domainId": "MAIL",
    "hubDomainId": "MAIL",
    "isForReference": false,
    "status": "releasedToVendor",
    "docStatus": "active",
    "editingStatus": "confirmed",
    "vpoNo": "28288",
    "vpoDate": "2021-02-23",
        "instructions": "METAL-No Size:1360600001-Article Number",
    "businessRefNo": "2818",
    "totalItems": 1,
    "totalQty": 160,
    "season": {
        "code": "F21"
    },
    "custId": {
        "refNo": "C000001"
    },
    "vendorId": {
        "vendorCode": "41843"
    },
    "headerFactory": {
        "refNo": "F000026",
        "factCode": "900088"
    },
    "vpoItemList": [
        {
            "itemNo": "19979-2021-0002-41843",
            "itemName": "Base Camp 6 Footprint",
            "customerItemNo": "19979",
            "lotNo": 1,
            "itemDesc": "Base Camp 6 Footprint",
                        "shipQty": 160,
                        "planedQty": 160,
                        "qtyPerExportCarton": 160,
            "qtyPerInnerCarton": 160,
            "factCode": "900088",
            "refNo": "19979-2021-0002-41843-1",
            "uom": {
                "code": "PCS"
            },
            "brand": {
                "code": "MAIL Co-op"
            },
            "itemId": {
                "itemNo": "19979-2021-0002-41843"
            },
            "portOfLoading": {
                "code": "DLC Dalian"
            },
            "vpoItemCsList": [
                {
                    "itemLotNo": "19979-2021-0002-41843-Lot1",
                    "vpoItemColorRef": "METAL",
                    "vpoItemColorId": {
                        "refNo": "METAL",
                        "shortName": "METAL"
                    },
                    "vpoItemSizeId": {
                        "refNo": "No Size",
                        "displayName": "No Size"
                    },
                    "itemId": {
                        "itemNo": "19979-2021-0002-41843"
                    },
                    "lotNo": 1
                }
            ],
            "factId": {
                "factCode": "900088"
            }
        },
        {
            "itemNo": "22825-2021-0001-43095",
            "itemName": "Flash 22 Member Exclusive",
            "customerItemNo": "22825",
            "lotNo": 1,
            "itemDesc": "Flash 22 Member Exclusive",
                        "shipQty": 160,
                        "planedQty": 160,
                        "qtyPerExportCarton": 160,
            "qtyPerInnerCarton": 160,
            "factCode": "900088",
            "refNo": "22825-2021-0001-43095-1",
            "uom": {
                "code": "PCS"
            },
            "brand": {
                "code": "MAIL Co-op"
            },
            "itemId": {
                "itemNo": "22825-2021-0001-43095"
            },
            "portOfLoading": {
                "code": "DLC Dalian"
            },
            "vpoItemCsList": [
                                {
                    "itemLotNo": "22825-2021-0001-43095-Lot1",
                    "vpoItemColorRef": "UNDYED",
                    "vpoItemColorId": {
                        "refNo": "UNDYED",
                        "shortName": "UNDYED"
                        },
                    "vpoItemSizeRef": "One Size",
                    "vpoItemSizeId": {
                        "refNo": "One Size",
                        "displayName": "One Size",
                        "sizeUniqueKey": "SIZE1"
                        },
                    "itemId": {
                        "itemNo": "22825-2021-0001-43095"
                        },
                    "lotNo": 1
                    
                }
            ],
            "factId": {
                "factCode": "900088"
            }
        }       
    ],
    "vpoShipDtlDtoGroupList": [
        [
            {
                "qty": 160,
                "refNo": "00001/19979-2021-0002-41843-1",
                "vpoItemRef": "19979-2021-0002-41843-1",
                "vpoItemId": {
                    "itemId": {
                        "itemNo": "19979-2021-0002-41843"
                    }
                },
                "vpoShipRef": "00001",
                "vpoShipId": {
                    "shipmentNo": "00001",
                    "originalShipmentDate": "2021-08-17",
                    "shipmentDate": "2021-08-23",
                    "originalInDcDate": "2021-09-15",
                    "inDcDate": "2021-09-15",
                    "refNo": "00001/19979-2021-0002-41843-1",
                    "shipMode": {
                        "code": "3"
                    },
                    "finalDestination": {
                            "code": "0001"
                            },
                            "portOfLoading": {
                        "code": "DLC Dalian"
                    }
                },
                "shipMode": {
                    "code": "3"
                            },
                            "portOfLoading": {
                            "code": "DLC Dalian"
                }
            },
                  {
                "qty": 630,
                "refNo": "00001/22825-2021-0001-43095-1",
                "vpoItemRef": "22825-2021-0001-43095-1",
                "vpoItemId": {
                    "itemId": {
                        "itemNo": "22825-2021-0001-43095"
                    }
                },
                "vpoShipRef": "00001",
                "vpoShipId": {
                    "shipmentNo": "00001",
                    "originalShipmentDate": "2021-08-17",
                    "shipmentDate": "2021-08-23",
                    "originalInDcDate": "2021-09-15",
                    "inDcDate": "2021-09-15",
                    "refNo": "00001/19979-2021-0002-41843-1",
                    "shipMode": {
                        "code": "3"
                    },
                    "finalDestination": {
                            "code": "0001"
                            },
                            "portOfLoading": {
                        "code": "DLC Dalian"
                    }
                },
                "shipMode": {
                    "code": "3"
                            },
                            "portOfLoading": {
                            "code": "DLC Dalian"
                }
            }
        ]
    ],
    "vpoShipDtlCsGroupList": [
        [
            {
                "itemLotNo": "19979-2021-0002-41843-Lot1",
                "shipmentNo": "00001",
                "colorSizeQty": 160,
                "refNo": "00001/19979-2021-0002-41843-1/METAL/No Size",
                "vpoItemRef": "19979-2021-0002-41843-1",
                "vpoItemId": {
                    "itemId": {
                        "itemNo": "19979-2021-0002-41843"
                    }
                },
                "vpoShipRef": "00001/19979-2021-0002-41843-1",
                "vpoItemColorRef": "METAL",
                "vpoItemSizeRef": "No Size",
                "vpoShipDtlColorRef": "1",
                "vpoShipDtlSizeRef": "1"
            }
        ],
        [
                        {
                "itemLotNo": "22825-2021-0001-43095-Lot1",
                "shipmentNo": "00001",
                "colorSizeQty": 630,
                "refNo": "00001/22825-2021-0001-43095-1/UNDYED/One Size",
                "vpoItemRef": "22825-2021-0001-43095-1",
                "itemSizeId": "035ae556951b413588cb935fe8abe89e",
                "itemColorId": "92bdbbe775cd470dbfaba3b58597f0a8",
                "itemColor": {},
                "vpoItemId": {
                    "itemId": {
                        "itemNo": "22825-2021-0001-43095"
                         }
                    
                },
                "vpoShipRef": "00001/22825-2021-0001-43095-1",
                "vpoItemColorRef": "UNDYED",
                "vpoItemSizeRef": "One Size",
                "vpoShipDtlColorRef": "1",
                "vpoShipDtlSizeRef": "1"
            }
        ]
    ]
}

谢谢, 拉维

arrays xslt multidimensional-array xml-parsing xslt-2.0
1个回答
0
投票

虽然您使用 XSLT 3,但尚不清楚为什么将其标记为 XSLT 2.0。

一般来说,如果您有多个同名的子元素,并且想要将它们“集中”在一起,作为数组成员,在 JSON 表示中,您可以考虑使用

xsl:for-each-group select="*" group-by="node-name()"
,然后,如果有多个子元素组中的一项(例如
<xsl:choose><xsl:when test="current-group()[2]">
)输出您需要的数组,否则进行正常处理以构造地图。

我没有完整的、脱离 shell 代码来处理所有选项,使用分组构造数组的示例是

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    xmlns="http://www.w3.org/2005/xpath-functions"
    expand-text="yes"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:template match="/">
      <xsl:variable name="json-xml">
          <xsl:apply-templates/>
      </xsl:variable>
      <xsl:value-of select="xml-to-json($json-xml, map { 'indent' : true() })"/>
  </xsl:template>
  
  <xsl:template match="*[not(*)]">
    <string key="{local-name()}">{.}</string>
  </xsl:template>
  
  <xsl:template match="*[not(*) and . castable as xs:double]">
    <number key="{local-name()}">{.}</number>
  </xsl:template>
  
  <xsl:template match="*[*]">
      <map>
          <xsl:for-each-group select="*" group-by="node-name()">
              <xsl:choose>
                  <xsl:when test="current-group()[2]">
                      <array key="{local-name()}">
                          <xsl:apply-templates select="current-group()"/>
                      </array>
                  </xsl:when>
                  <xsl:otherwise>
                      <xsl:apply-templates select="current-group()"/>
                  </xsl:otherwise>
              </xsl:choose>
          </xsl:for-each-group>
      </map>
  </xsl:template>

</xsl:stylesheet>

这会改变例如

<root>
    <item>
        <number>3.14</number>
        <name>foo</name>
    </item>
    <item>
        <number>42</number>
        <name>bar</name>
    </item>
    <data>test</data>
</root>

进入

{ "item" : 
    [ 
      { "number" : 3.14,
        "name" : "foo" },
      
      { "number" : 42,
        "name" : "bar" } ],
    "data" : "test" }

您可能需要改进/扩展/适应您的需求。

© www.soinside.com 2019 - 2024. All rights reserved.