【问题标题】:Sort and group in xml to json conversionxml到json转换中的排序和分组
【发布时间】:2021-05-27 09:04:31
【问题描述】:

我正在尝试根据“地址”中的“itemLotNo”对订单项进行排序和分组。当地址中的 lineitems 相同时,应该在方括号或 Array Address[[{...},{...}],[{...}],[{...}]] 之间形成.

数据应该保持不变,即在 lineitems 没有变化的情况下,只需要对相同的 'itemLotNo' 进行排序和分组。

xml文件:

<root>
    <FirstName>Alex</FirstName>
    <LastName>Fin</LastName>
    <Details>
        <Id_Number>111</Id_Number>
        <Location>NC</Location>
        <Contact>
            <PhoneNumber>+1 323</PhoneNumber>
        </Contact>
    </Details>
    <Details>
        <Id_Number>222</Id_Number>
        <Location>TX</Location>
        <Contact>
            <PhoneNumber>+1 323</PhoneNumber>
        </Contact>
    </Details>
    <Address>
        <itemLotNo>19949-2018-0001-45116-Dot1</itemLotNo>
        <Locality>Urban</Locality>
        <Type>Mobile</Type>
    </Address>
    <Address>
        <itemLotNo>19950-2018-0001-45116-Dot1</itemLotNo>
        <Locality>Rural</Locality>
        <Type>Landline</Type>
    </Address>
    <Address>
        <itemLotNo>19949-2018-0001-45116-Dot1</itemLotNo>
        <Locality>Rural</Locality>
        <Type>Landline</Type>
    </Address>
    <Address>
        <itemLotNo>19958-2018-0001-45116-Dot1</itemLotNo>
        <Locality>Rural</Locality>
        <Type>Landline</Type>
    </Address>
</root>

ExpectedJsonFile:

{
  "FirstName": "Alex",
  "LastName": "Fin",
  "Details": [
    [
      {
        "Id_Number": "111",
        "Location": "NC",
        "Contact": {
          "PhoneNumber": "+1 323"
        }
      },
      {
        "Id_Number": "222",
        "Location": "TX",
        "Contact": {
          "PhoneNumber": "+1 323"
        }
      }
    ]
  ],
  "Address": [
    [
      {
        "itemLotNo": "19949-2018-0001-45116-Dot1",
        "Locality": "Urban",
        "Type": "Mobile"
      },
      {
        "itemLotNo": "19949-2018-0001-45116-Dot1",
        "Locality": "Rural",
        "Type": "Landline"
      }
    ],
    [
      {
        "itemLotNo": "19950-2018-0001-45116-Dot1",
        "Locality": "Rural",
        "Type": "Landline"
      }
    ],
    [
      {
        "itemLotNo": "19958-2018-0001-45116-Dot1",
        "Locality": "Rural",
        "Type": "Landline"
      }
    ]
  ]
}

xslt代码:

<?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::Details or self::Address">
                  <array key="{local-name()}">
                    <xsl:choose>
                      <xsl:when test="self::Details">
                        <array>
                          <xsl:apply-templates select="current-group()">
                            <xsl:with-param name="key" select="false()"/>
                          </xsl:apply-templates>                        
                        </array>
                      </xsl:when>
<xsl:when test="self::Address">
                        <xsl:iterate select="current-group()">
<array>
                          <xsl:apply-templates select="self::Address">

                          </xsl:apply-templates>                        
                        </array>
                        </xsl:iterate>
                      </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>

【问题讨论】:

    标签: json xml xml-parsing xslt-2.0 xslt-3.0


    【解决方案1】:

    有了Address的特殊待遇看来你想要

      <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::Details or self::Address">
                      <array key="{local-name()}">
                        <xsl:choose>
                          <xsl:when test="self::Details">
                            <array>
                              <xsl:apply-templates select="current-group()">
                                <xsl:with-param name="key" select="false()"/>
                              </xsl:apply-templates>                        
                            </array>
                          </xsl:when>
                          <xsl:when test="self::Address">
                            <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>
    

    【讨论】:

    • .....非常感谢马丁的支持......它按预期工作。
    • @raviteja,如果您的问题得到解决,请考虑将答案标记为已接受。
    【解决方案2】:

    如果你把最后一个模板改成这样:

      <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::Details or self::Address">
                <array key="{local-name()}">
                  <xsl:choose>
                    <xsl:when test="self::Details">
                        <xsl:apply-templates select="current-group()">
                          <xsl:with-param name="key" select="false()"/>
                        </xsl:apply-templates>                        
                    </xsl:when>
                    <xsl:when test="self::Address">
                      <xsl:iterate select="current-group()">
                        <xsl:apply-templates select="self::Address"/>
                      </xsl:iterate>
                    </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>
    

    你会得到这个json:

    {
      "FirstName": "Alex",
      "LastName": "Fin",
      "Details": [
        {
          "Id_Number": "111",
          "Location": "NC",
          "Contact": {"PhoneNumber": "+1 323"}
        },
        {
          "Id_Number": "222",
          "Location": "TX",
          "Contact": {"PhoneNumber": "+1 323"}
        }
      ],
      "Address": [
        {
          "itemLotNo": "19949-2018-0001-45116-Dot1",
          "Locality": "Urban",
          "Type": "Mobile"
        },
        {
          "itemLotNo": "19950-2018-0001-45116-Dot1",
          "Locality": "Rural",
          "Type": "Landline"
        },
        {
          "itemLotNo": "19949-2018-0001-45116-Dot1",
          "Locality": "Rural",
          "Type": "Landline"
        },
        {
          "itemLotNo": "19958-2018-0001-45116-Dot1",
          "Locality": "Rural",
          "Type": "Landline"
        }
      ]
    }
    

    这与您的 ExpectedJsonFile 不同,因为它没有 Address 和 Details 的嵌套数组,但也许它更好。 See json question about array of objects.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-14
      • 2014-01-17
      • 1970-01-01
      • 2012-08-16
      • 2021-01-30
      • 1970-01-01
      • 2013-03-26
      • 2018-02-07
      相关资源
      最近更新 更多