在xml到json的转换中进行排序和分组



我试图根据"Address"中的"itemLotNo"对行项目进行排序和分组。当行项目在Address中相同时,这些行项目应形成在方括号或Array Address[[…},{…}],[[…}],[{…}]]之间。

数据应保持不变,即行项目无变化,只需对相同的"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>

预期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": "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"
}
]
]
}

xsltCode:

<?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>

通过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>

如果您将最后一个模板更改为:

<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的嵌套数组,但可能更好。请参阅关于对象数组的json问题。

最新更新