【问题标题】:Using XSLT to transform XML to JSON and add 2 Square bracket [[]]使用 XSLT 将 XML 转换为 JSON 并添加 2 个方括号 [[]]
【发布时间】:2021-07-21 08:08:33
【问题描述】:

请求共享用于 xml 到 json 转换的 xslt 代码。 我们需要将 xml 转换为 json。然后修剪 OuterElement 和多个方括号 [[ a) 修剪外部元素 b) 带有 2 个方括号 [[

输入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>2826118</vpoNo>
    <vpoDate>2021-02-23</vpoDate>
    <instructions>METAL-No Size:1360600001-Article Number</instructions>
    <businessRefNo>826118</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</code>
        </brand>
        <itemId>
            <itemNo>19979-2021-0002-41843</itemNo>
        </itemId>
        <portOfLanding>
            <code>DLC Dalian</code>
        </portOfLanding>
        <vpoItemCsList>
            <itemLotNo>19979-2021-0002-41843-Lot1</itemLotNo>
            <vpoItemColorRef>METAL</vpoItemColorRef>
            <vpoItemColorId>
                <refNo>GUNMETAL</refNo>
                <shortName>METAL</shortName>
            </vpoItemColorId>
            <vpoItemSizeId>
                <refNo>No Size</refNo>
                <displayName>No Size</displayName>
            </vpoItemSizeId>
            <itemId>
                <iteamNo>19979-2021-0002-41843</iteamNo>
            </itemId>
            <lotNo>1</lotNo>
        </vpoItemCsList>
        <factId>
            <factCode>900088</factCode>
        </factId>
    </vpoItemList>
    <vpoShipDtlDtoGroupList>
        <qty>160</qty>
        <refNo>00001/19979-2021-0002-41843-1</refNo>
        <vpoItemRef
            xmlns:ns1="http://sap.com/xi/SAPGlobal/GDT">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>
    <vpoShipDtlCsGroupList>
        <itemLotNo>19979-2021-0002-41843-Lot1</itemLotNo>
        <shipmentNo>00001</shipmentNo>
        <colorSizeQty>160</colorSizeQty>
        <refNo>00001/19979-2021-0002-41843-1/GUNMETAL/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>
</ns0:PO_Message>

预期的 Json 输出文件

  { "domainId" : "MAIL",
    "hubDomainId" : "MAIL",
    "isForReference" : "false",
    "status" : "releasedToVendor",
    "docStatus" : "active",
    "editingStatus" : "confirmed",
    "vpoNo" : "2118",
    "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" : "Wide" },
        "itemId" : 
        { "itemNo" : "19979-2021-0002-41843" },
        "portOfLanding" : 
        { "code" : "DLC Dalian" },
        "vpoItemCsList" : 
        [ 
          { "itemLotNo" : "19979-2021-0002-41843-Lot1",
            "vpoItemColorRef" : "METAL",
            "vpoItemColorId" : 
            { "refNo" : "GUNMETAL",
              "shortName" : "METAL" },
            "vpoItemSizeId" : 
            { "refNo" : "No Size",
              "displayName" : "No Size" },
            "itemId" : 
            { "iteamNo" : "19979-2021-0002-41843" },
            "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" } } ] ],
    "vpoShipDtlCsGroupList" : 
    [ 
      [ 
        { "itemLotNo" : "19979-2021-0002-41843-Lot1",
          "shipmentNo" : "00001",
          "colorSizeQty" : "160",
          "refNo" : "00001\/19979-2021-0002-41843-1\/GUNMETAL\/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" } ] ] }

XLST 代码:

<?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 | vpoShipDtlCsGroupList" priority="10">
    <array key="{local-name()}">
        <array>
          <map>
            <xsl:apply-templates/>
          </map>          
        </array>
    </array>
  </xsl:template>

</xsl:stylesheet>

谢谢, 拉维

【问题讨论】:

  • 您是否知道 XSLT 和 XPath 3 以 XML 格式表示 JSON w3.org/TR/xpath-functions/#json-to-xml-mapping 的内置功能,然后您可以使用函数 xml-to-json 将其转换为 JSON?因此,您所需要的只是一个 XML 到 XML 的转换,将您的输入映射到函数期望的格式,然后应用它。试一试,遇到困难时再回来。
  • 嗨 Martin,我尝试使用以下代码,但输出与预期不符。请求检查和修改代码以获得预期的输出。w3.org/1999/XSL/Transform" xmlns="w3.org/2005/xpath-functions">
  • 请将您的代码放入问题中格式良好的代码示例中,而不是 cmets。并且需要一些时间来了解xml-to-json 函数期望的格式,没有神奇的任意 XML 到 JSON 的转换,正如我所说,你首先需要编写模板来将你的 XML 转换为函数期望的格式。

标签: arrays json multidimensional-array xslt-2.0 xslt-3.0


【解决方案1】:

这基本上是从您的 XML 到 xml-to-json 函数期望的 XML 格式的两步转换。你会使用

<?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="xml" indent="yes"/>

  <xsl:mode on-no-match="shallow-skip"/>
  
  <xsl:template match="/*">
    <map>
      <xsl:apply-templates/>
    </map>
  </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="*[* and not(*[2])]">
    <map key="{local-name()}">
        <xsl:apply-templates/>
    </map>
  </xsl:template>
  
  <xsl:template match="*[* and *[2]]">
    <array key="{local-name()}">
        <map>
          <xsl:apply-templates/>
        </map>
    </array>
  </xsl:template>
  
  <xsl:template match="ShipGroupList | ShipmentRefference" priority="10">
    <array key="{local-name()}">
        <array>
          <map>
            <xsl:apply-templates/>
          </map>          
        </array>
    </array>
  </xsl:template>

  <xsl:template match="/" name="xsl:initial-template">
    <xsl:next-match/>
    <xsl:comment xmlns:saxon="http://saxon.sf.net/">Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}</xsl:comment>
  </xsl:template>

</xsl:stylesheet>

对于给出 (https://xsltfiddle.liberty-development.net/asoTJB/0) 的第一步,例如

<?xml version="1.0" encoding="UTF-8"?>
<array xmlns="http://www.w3.org/2005/xpath-functions" key="PO_Message">
   <map>
      <string key="domainId">Mail</string>
      <string key="hubId">Mail</string>
      <array key="MailItemList">
         <map>
            <string key="itemNo">2021-0002</string>
            <string key="itemName">Camp</string>
            <map key="factId">
               <number key="factCode">188</number>
            </map>
         </map>
      </array>
      <array key="ShipGroupList">
         <array>
            <map>
               <number key="GroupList1">123</number>
               <number key="qty">160</number>
               <map key="shipMode">
                  <number key="code">3</number>
               </map>
            </map>
         </array>
      </array>
      <array key="ShipmentRefference">
         <array>
            <map>
               <number key="itemLotNo">199791</number>
               <number key="shipmentNo">1</number>
            </map>
         </array>
      </array>
   </map>
</array>
<!--Run with SAXON HE 9.8.0.15 -->

那么完整的样式表将使用变量中的第一步并将xml-to-json 函数应用于变量:

<?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="*[not(*) and . castable as xs:double]">
    <number key="{local-name()}">{.}</number>
  </xsl:template>
  
  <xsl:template match="*[* and not(*[2])]">
    <map key="{local-name()}">
        <xsl:apply-templates/>
    </map>
  </xsl:template>
  
  <xsl:template match="*[* and *[2]]">
    <array key="{local-name()}">
        <map>
          <xsl:apply-templates/>
        </map>
    </array>
  </xsl:template>
  
  <xsl:template match="ShipGroupList | ShipmentRefference" priority="10">
    <array key="{local-name()}">
        <array>
          <map>
            <xsl:apply-templates/>
          </map>          
        </array>
    </array>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/asoTJB/1

【讨论】:

  • 感谢 Martin,json 文件在几个 lineitems 中有额外的方括号。
  • 感谢 Martin,json 文件在标题部分“headerFactory”中有额外的方括号,因为内部 lineitems 不是数组。请求检查代码以删除方括号 [ 用于 lineitems a) "vpoItemColorId", b) "vpoItemSizeId", c) "itemId" 我们使用 saxon-ee-10.5.jar 进行转换。
  • @raviteja,您获得了指向xml-to-json 函数期望格式的文档的链接以及带有工作示例和原始输入示例的答案;如果您在收到答案后编辑问题并更改输入数据,请不要指望我们实施任何改进。尝试从答案中学习并使其适应您的需求。
  • 嗨,马丁,我已将 xslt 文件修改为
  • 嗨 Martin - 我已将值转换为 1 而不是“0001”。请求检查“vpoShipId”的阵列问题[
猜你喜欢
  • 2021-01-05
  • 2020-10-28
  • 2014-05-03
  • 2020-01-26
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2019-12-28
相关资源
最近更新 更多