Пустые элементы в преобразовании xml в json

#json #xml-parsing #xslt-1.0 #xslt-2.0 #xslt-grouping

Вопрос:

Файл json должен работать в соответствии с приведенным ниже кодом xsl, иначе должны быть заполнены пустые теги в файле json, оба сценария должны работать. когда у нас есть значения в узлах xml, он должен работать так, как показано ниже в файле json.

Xsl-код должен работать для обоих сценариев.

xml-файл:

     <?xml version="1.0" encoding="UTF-8"?>
    <ns0:PO_Record
        xmlns:ns0="http://Test.com/Order">
        <domainId>TEST</domainId>
        <hubDomainId>TEST</hubDomainId>
        <isForReference>false</isForReference>
        <status>releasedToVendor</status>
        <docStatus>active</docStatus>
        <editingStatus>confirmed</editingStatus>
        <vpoNo>10000341</vpoNo>
        <vpoDate>2021-05-11</vpoDate>
        <instructions>STONE GREY-XS:060000</instructions>
        <businessRefNo>10000341</businessRefNo>
        <totalItems>1</totalItems>
        <totalQty>5</totalQty>
        <customFields>
            <customFieldDate1>2021-11-01</customFieldDate1>
        </customFields>
        <season>
            <code>F20</code>
        </season>
        <custId>
            <custCode>TEST</custCode>
            <refNo>C000001</refNo>
        </custId>
        <vendorId>
            <vendorCode>46211</vendorCode>
        </vendorId>
        <vpoItemList>
            <itemNo>12345-2020-1002-45671</itemNo>
            <itemName>Wallace</itemName>
            <customerItemNo>21916</customerItemNo>
            <lotNo>1</lotNo>
            <itemDesc>Wallace</itemDesc>
            <shipQty>5</shipQty>
            <planedQty>5</planedQty>
            <qtyPerExportCarton>5</qtyPerExportCarton>
            <qtyPerInnerCarton>5</qtyPerInnerCarton>
            <factCode>0000444488</factCode>
            <refNo>12345-2020-1002-45671-1</refNo>
            <uom>
                <code>PCS</code>
            </uom>
            <brand>
                <code>TEST Co-op</code>
            </brand>
            <itemId>
                <itemNo>12345-2020-1002-45671</itemNo>
            </itemId>
            <portOfLanding>
                <code>City</code>
            </portOfLanding>
            <vpoItemCsList>
                <itemLotNo>12345-2020-1002-45671-Lot1</itemLotNo>
                <vpoItemColorRef>STONE</vpoItemColorRef>
                <vpoItemColorId>
                    <refNo>STONE</refNo>
                    <shortName>STONE</shortName>
                </vpoItemColorId>
                <vpoItemSizeId>
                    <refNo>XS</refNo>
                    <displayName>XS</displayName>
                </vpoItemSizeId>
                <itemId>
                    <itemNo>12345-2020-1002-45671</itemNo>
                </itemId>
                <lotNo>1</lotNo>
            </vpoItemCsList>
            <factId>
                <factCode>902397</factCode>
            </factId>
        </vpoItemList>
        <vpoShipDtlDtoGroupList>
            <qty>5</qty>
            <refNo>00001/12345-2020-1002-45671-1</refNo>
            <vpoItemRef
                xmlns:ns1="http://sap.com/xi/SAPGlobal/GDT">12345-2020-1002-45671-1
            </vpoItemRef>
            <vpoItemId>
                <itemId>
                    <itemNo>12345-2020-1002-45671</itemNo>
                </itemId>
            </vpoItemId>
            <vpoShipRef>00001</vpoShipRef>
            <vpoShipId>
                <shipmentNo>00001</shipmentNo>
                <originalShipmentDate>2021-11-01</originalShipmentDate>
                <shipmentDate>2021-11-05</shipmentDate>
                <originalInDcDate>2021-12-29</originalInDcDate>
                <inDcDate>2021-12-29</inDcDate>
                <refNo>00001/12345-2020-1002-45671-1</refNo>
                <shipMode>
                    <code>3</code>
                </shipMode>
                <finalDestination>
                    <code>0001</code>
                </finalDestination>
                <portOfLoading>
                    <code>City</code>
                </portOfLoading>
            </vpoShipId>
            <shipMode>
                <code>3</code>
            </shipMode>
            <portOfLoading>
                <code>City</code>
            </portOfLoading>
        </vpoShipDtlDtoGroupList>
        <vpoShipDtlCsGroupList>
            <itemLotNo>12345-2020-1002-45671-Lot1</itemLotNo>
            <shipmentNo>00001</shipmentNo>
            <colorSizeQty>5</colorSizeQty>
            <skuNo>1407600001</skuNo>
            <refNo>00001/12345-2020-1002-45671-1/STONE/XS</refNo>
            <vpoItemRef>12345-2020-1002-45671-1</vpoItemRef>
            <vpoItemId>
                <itemId>
                    <itemNo>12345-2020-1002-45671</itemNo>
                </itemId>
            </vpoItemId>
            <vpoShipRef>00001/12345-2020-1002-45671-1</vpoShipRef>
            <vpoItemColorRef>STONE</vpoItemColorRef>
            <vpoItemSizeRef>XS</vpoItemSizeRef>
            <vpoShipDtlColorRef>1</vpoShipDtlColorRef>
            <vpoShipDtlSizeRef>1</vpoShipDtlSizeRef>
        </vpoShipDtlCsGroupList>
    </ns0:PO_Record>
 

Файл Json:
{ «domainId» : «тест»,
«hubDomainId» : «тест»,
«isForReference» : «ложь»,
«статус» : «releasedToVendor»,
«docStatus» : «активный»,
«editingStatus» : «подтверждено»,
«vpoNo» : «10000341»,
«vpoDate» : «2021-05-11»,
«инструкции» : «серый камень-хз:060000»,
«businessRefNo» : «10000341»,
«totalItems» : «1»,
«totalQty» : «5»,
«customFields» :
{ «customFieldDate1» : «2021-11-01» },
«сезон» :
{ «код» : «F20» },
«кустИд» :
{ «custCode» : «ТЕСТ»,
«RefNo» : «C000001» },
«Идентификатор поставщика» :
{ «Код поставщика» : «46211» },
«vpoItemList» :
[
{ «ItemNo» : «12345-2020-1002-45671»,
«Имя элемента» : «Уоллес»,
«customerItemNo» : «21916»,
«lotNo» : «1»,
«itemDesc» : «Уоллес»,
«shipQty» : «5»,
«planedQty» : «5»,
«qtyPerExportCarton» : «5»,
«qtyPerInnerCarton» : «5»,
«factCode» : «0000444488»,
«refNo» : «12345-2020-1002-45671-1»,
«ЕИ» :
{ «код» : «ШТ» },
«марка» :
{ «код» : «ТЕСТОВЫЙ кооператив» },
«Идентификатор элемента» :
{ «ItemNo» : «12345-2020-1002-45671» },
«портОфЛэндинг» :
{ «код» : «Город» },
«vpoItemCsList» :
[
{ «itemLotNo» : «12345-2020-1002-45671-Лот1»,
«vpoItemColorRef» : «КАМЕНЬ»,
«vpoItemColorId» :
{ «RefNo» : «КАМЕНЬ»
, «КРАТКОЕ имя» : «КАМЕНЬ»},
«vpoItemSizeId» :
{ «RefNo» : «XS»,
«Имя дисплея» : «XS» },
«ItemId» :
{ «Предметно» : «12345-2020-1002-45671» },
«лотНо» : «1» } ],
«Факт» :
{ «Код факта» : «902397» } } ],
«vposhipdtldтогруппа» :
[
[
{ «кол-во» : «5»,
«рефНо» : «00001/12345-2020-1002-45671-1»,
«vpoItemRef» : «12345-2020-1002-45671-1ntt»,
«vpoItemId» :
{ «ItemId» :
{ «ItemNo» : «12345-2020-1002-45671» } },
«vpoShipRef» : «00001»,
«vpoShipId» :
{ «отправлеНо» : «00001»,
«Дата отправки» : «2021-11-01»,
«Дата отправки» : «2021-11-05»,
«Дата отправки» : «2021-12-29»,
«Дата отправки» : «2021-12-29»,
«RefNo» : «00001/12345-2020-1002-45671-1»,
«Режим судна» :
{ «код» : «3» },
«Окончательное определение» :
{ «код» : «0001» },
«Загрузка портов» :
{ «код» : «Город» } },
«Режим судна» :
{ «код» : «3» },
«Загрузка портов» :
{ «код» : «Город» } } ] ],
«vpoShipDtlCsGroupList» :
[
[
{ «itemLotNo» : «12345-2020-1002-45671-Lot1»,
«shipmentNo» : «00001»,
«colorSizeQty» : «5»,
«skuNo» : «1407600001»,
«refNo» : «00001/12345-2020-1002-45671-1/Камень/хз»,
«vpoItemRef» : «12345-2020-1002-45671-1»,
«vpoItemId» :
{ «ItemId» :
{ «ItemNo» : «12345-2020-1002-45671» } },
«vpoShipRef» : «00001/12345-2020-1002-45671-1»,
«vpoItemColorRef» : «КАМЕНЬ»,
«vpoItemSizeRef» : «XS»,
«vpoShipDtlColorRef» : «1»,
«vpoShipDtlSizeRef» : «1» } ] ] }

 xslt code:    
            <?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="*[(*) and . castable as xs:double]">
                <number key="{local-name()}">{.}</number>
              </xsl:template>
              
               <xsl:template match="*[*]">
                <xsl:param name="key" as="xs:boolean" select="false()"/>
                <map>
                  <xsl:if test="$key">
                    <xsl:attribute name="key" select="local-name()"/>
                  </xsl:if>
                  <xsl:for-each-group select="*" group-by="node-name()">
                      <xsl:choose>
                          <xsl:when test="current-group()[2] or self::vpoItemList or self::vpoItemCsList or self::vpoShipDtlDtoGroupList or self::vpoShipDtlCsGroupList">
                              <array key="{local-name()}">
                                <xsl:choose>
                                  <xsl:when test="self::vpoShipDtlDtoGroupList">
                                    <array>
                                      <xsl:apply-templates select="current-group()">
                                        <xsl:with-param name="key" select="false()"/>
                                      </xsl:apply-templates>                        
                                    </array>
                                  </xsl:when>
                                  <xsl:when test="self::vpoShipDtlCsGroupList">
                                    <xsl:for-each-group select="current-group()" group-by="itemLotNo">
                                      <array>
                                        <xsl:apply-templates select="current-group()">
                                          <xsl:with-param name="key" select="false()"/>
                                        </xsl:apply-templates>
                                      </array>
                                    </xsl:for-each-group>
                                  </xsl:when>
                                  <xsl:otherwise>
                                    <xsl:apply-templates select="current-group()">
                                      <xsl:with-param name="key" select="false()"/>
                                    </xsl:apply-templates>
                                  </xsl:otherwise>                      
                                </xsl:choose>
                              </array>
                          </xsl:when>
                          <xsl:otherwise>
                              <xsl:apply-templates select="current-group()">
                                <xsl:with-param name="key" select="true()"/>
                              </xsl:apply-templates>
                          </xsl:otherwise>
                      </xsl:choose>
                  </xsl:for-each-group>
                </map>
              </xsl:template>
            </xsl:stylesheet>

                              </array>
                            </xsl:for-each-group>
                          </xsl:when>
                          <xsl:otherwise>
                            <xsl:apply-templates select="current-group()">
                              <xsl:with-param name="key" select="false()"/>
                            </xsl:apply-templates>
                          </xsl:otherwise>                      
                        </xsl:choose>
                      </array>
                  </xsl:when>
                  <xsl:otherwise>
                      <xsl:apply-templates select="current-group()">
                        <xsl:with-param name="key" select="true()"/>

                      </xsl:apply-templates>

                  </xsl:otherwise>

              </xsl:choose>
          </xsl:for-each-group>
        </map>
      </xsl:template>    
    </xsl:stylesheet>
 

Second scenario: when we dont have data in the xml nodes

  Input xml file:
    <?xml version="1.0" encoding="UTF-8"?>
    <ns0:PO_Record
        xmlns:ns0="http://Test.com/Order">
        <domainId>TEST</domainId>
        <hubDomainId>TEST</hubDomainId>
        <isForReference>false</isForReference>
        <status>Ok</status>
        <docStatus>Success</docStatus>
        <editingStatus>confirmed</editingStatus>
        <vpoNo>10000341</vpoNo>
        <vpoDate>2021-03-05</vpoDate>
        <instructions></instructions>
        <businessRefNo>10000341</businessRefNo>
        <totalItems>0</totalItems>
        <totalQty>0</totalQty>
        <customFields>
            <customFieldDate1>2042-01-21</customFieldDate1>
        </customFields>
        <season>
            <code>F22</code>
        </season>
        <custId>
            <custCode>TEST</custCode>
            <refNo>002001</refNo>
        </custId>
        <vendorId>
            <vendorCode>1235</vendorCode>
        </vendorId>
        <vpoItemList></vpoItemList>
        <vpoShipDtlDtoGroupList></vpoShipDtlDtoGroupList>    
        <vpoShipDtlCsGroupList></vpoShipDtlCsGroupList>
    </ns0:PO_Record>
 

Ожидаемый файл Json:
{ «Доменный идентификатор» : «ТЕСТ», «Доменный идентификатор» : «ТЕСТ», «isForReference» : «ложь», «статус» : «Ок», «Статус документа» : «Успешно», «Статус редактирования» : «подтверждено», «vpoNo» : «10000341», «vpoDate» : «2021-03-05», «инструкции» : «», «businessRefNo» : «10000341», «Всего» : «0», «totalQty» : «0», «Пользовательские поля» : { «customFieldDate1» : «2042-01-21» }, «сезон» : { «код» : «F22» }, «кустИд» : { «custCode» : «ТЕСТ», «RefNo» : «002001» }, «Идентификатор поставщика» : { «Код поставщика» : «1235» }, «vpoItemList» : [ ], «vpoShipDtlDtoGroupList» : [ ], «Список групп vpoShipDtlCsGroupList» : [ ] }

Комментарии:

1. Изменения кода не работают для обоих сценариев…..Необходимо проверить once….</xsl:apply-templates></xsl:apply-templates></array></array></xsl:for-each-group></xsl:for-each-group></xsl:when></xsl:when><xsl:otherwise><xsl:otherwise><xsl:apply-шаблоны выберите=»текущая группа()»><xsl:применить-шаблоны выберите=»текущая группа()»><xsl:с именем параметра=»ключ» выберите=»ложь()»/><xsl:с именем параметра=»ключ» select=»false()»/></xsl:apply-templates></xsl:apply-templates></xsl:otherwise></xsl:otherwise></xsl:choose></xsl:choose></array></array></xsl:when></xsl:when><xsl:otherwise><xsl:otherwise><xsl:apply-шаблоны выберите=»текущая группа()»><xsl:применить-шаблоны выберите=»текущая группа()»><xsl:с именем параметра=»ключ» выберите=»истина()»/><xsl:с именем параметра=»ключ» select=»true()»/></xsl:apply-templates></xsl:apply-templates></xsl:otherwise></xsl:otherwise></xsl:choose></xsl:choose></xsl:for-each-group></xsl:for-each-group></map></map></xsl:template></xsl:template></xsl:stylesheet>