xml到json转换中的空标签

Posted

技术标签:

【中文标题】xml到json转换中的空标签【英文标题】:Empty tags in xml to json conversion 【发布时间】:2021-11-22 01:09:06 【问题描述】:

尝试在不干扰 xsl 代码中现有逻辑的情况下填充空标签。 Json 文件中应该只显示参数。

需要根据预期的json文件填充emptyp标签。

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>

ExpectedJsonFile: "domainId" : "测试", “hubDomainId”:“测试”, “isForReference”:“假”, “状态”:“好的”, "docStatus" : "成功", "editingStatus" : "已确认", “vpoNo”:“10000341”, “vpoDate”:“2021-03-05”, “指示” : ””, “businessRefNo”:“10000341”, “totalItems”:“0”, “总数”:“0”, “自定义字段”: "customFieldDate1" : "2042-01-21" , “季节” : “代码”:“F22”, “客户标识”: "custCode" : "测试", "refNo" : "002001" , “供应商 ID”: “供应商代码”:“1235”, “vpoItemList”: [ ], “vpoShipDtlDtoGroupList”: [ ], “vpoShipDtlCsGroupList”: []

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>

【问题讨论】:

【参考方案1】:

也许更改最后一个模板以检查空组/元素,例如

              <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="not(current-group()[2]) and (self::vpoItemList or self::vpoShipDtlDtoGroupList or self::vpoShipDtlCsGroupList)">
                            <array key="local-name()"></array>
                          </xsl:when>
                          <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>

【讨论】:

当我们有 时代码失败 哪个“代码失败”,是您问题中的原始代码还是答案中建议的代码?无论如何,尝试向我们展示格式良好的示例数据并解释转换的规则,而不是将一些未格式化的 sn-ps 转储到 cmets 或问题中。 问题中的原始版本。当我们在 xml 节点中有数据时,它应该填充数据。 12345-2020-1002-45671Wallace500001/12345-2020-1002 -45671-112345-2020-1002-45671-Lot100001 在新问题中给出 - ***.com/questions/69402496/… 嗨 Martin - 原始场景因代码更改而失败...vpoItemList" : [ ], "vpoShipDtlDtoGroupList" : [ ],当我们在节点中有数据时不填充。

以上是关于xml到json转换中的空标签的主要内容,如果未能解决你的问题,请参考以下文章

在转换为 XML 之前更改 JSON 对象中的属性名称

C# - 如何将复杂的 json 转换为 XML,并将名称和值属性转换为标签

XML 到 JSON 的动态转换

使用 XSL 将 json 转换为 XML

PHP SimpleXML 中的 XML 到 JSON 转换

将带有嵌套标签的 XML 读入 Spark RDD,并转换为 JSON