XSLT to convert XML to JSON Array

773 views Asked by At

I am currently using SAP CPI to achieve this conversion. I have tried the regular XML to JSON converter available but was not able to achieve this requirement. I then set out to try and see if XSLT can help.

I am trying to convert the following XML payload:

<root>
    <ClientID>1</ClientID>
    <PackageID>650</PackageID>
    <SBUID>2187</SBUID>
    <CandidateID>456</CandidateID>
    <AssociateId>789</AssociateId>
    <FirstName>Meghana</FirstName>
    <MiddleName></MiddleName>
    <LastName>Rao</LastName>
    <FatherName>Satish</FatherName>
    <ContactNo>7530001169</ContactNo>
    <EmailID>[email protected]</EmailID>
    <AddressHistory>
        <Address>
            <SequenceNo>0</SequenceNo>
            <AddressLine>Kharghar,navi mumbai</AddressLine>
            <City>Maharashtra-Mumbai</City>
            <State>Maharashtra</State>
            <PinCode>410210</PinCode>
            <Country>India</Country>
            <Landmark></Landmark>
            <StayFrom>01-08-2013</StayFrom>
            <StayTo>06-08-2021</StayTo>
            <IsCurrentAddress>false</IsCurrentAddress>
            <IsPermanentAddress>false</IsPermanentAddress>
            <HouseNo></HouseNo>
            <AddressType>Current</AddressType>
            <DocList>
                <listofdocs>
                    <DocumentName>abc.jpg</DocumentName>
                    <DocumentPath>base64</DocumentPath>
                </listofdocs>
            </DocList>
        </Address>
    </AddressHistory>
    <EducationList>
        <Education>
            <SequenceNo>0</SequenceNo>
            <Qualification></Qualification>
            <Degree>Under Graduate Degree</Degree>
            <CollegeName>Amrutvahini College of engineering, Sangamner (Pune University)</CollegeName>
            <Location></Location>
            <RollNumber>123123</RollNumber>
            <UniversityName>Mumbai University</UniversityName>
            <UniversityAddress></UniversityAddress>
            <PeriodFrom></PeriodFrom>
            <PeriodTo></PeriodTo>
            <YearOfPassing>2014</YearOfPassing>
            <Zipcode></Zipcode>
            <Percentage></Percentage>
            <AdditionalRemarks>10th/12th/Undergrad etc</AdditionalRemarks>
            <International>false</International>
            <Country></Country>
            <DocList>
                <listofdocs>
                    <DocumentName>abc.jpg</DocumentName>
                    <DocumentPath>base64</DocumentPath>
                </listofdocs>
            </DocList>
        </Education>
    </EducationList>
    <EmploymentList>
        <Employment>
            <SequenceNo>0</SequenceNo>
            <EmployerName>Stravis Solutions</EmployerName>
            <EmployerAddress>Bangalore</EmployerAddress>
            <EmployerContactNo></EmployerContactNo>
            <Designation>SDE</Designation>
            <EmployeeID>asdas</EmployeeID>
            <FixedSalary>0</FixedSalary>
            <IsCurrentEmployment>false</IsCurrentEmployment>
            <RelievingDate>15-10-2021</RelievingDate>
            <State></State>
            <City></City>
            <Zipcode></Zipcode>
            <International>false</International>
            <Country></Country>
            <PFNumber></PFNumber>
            <UANNumber></UANNumber>
            <DocList>
                <listofdocs>
                    <DocumentName>abc.jpg</DocumentName>
                    <DocumentPath>base64</DocumentPath>
                </listofdocs>
            </DocList>
            <DateOfJoining>18-03-2015</DateOfJoining>
        </Employment>
        <Employment>
            <SequenceNo>0</SequenceNo>
            <EmployerName>Stravis Solutions</EmployerName>
            <EmployerAddress>Bangalore</EmployerAddress>
            <EmployerContactNo></EmployerContactNo>
            <Designation>SDE</Designation>
            <EmployeeID>asdas</EmployeeID>
            <FixedSalary>0</FixedSalary>
            <IsCurrentEmployment>false</IsCurrentEmployment>
            <RelievingDate>15-10-2021</RelievingDate>
            <International>false</International>
            <Country></Country>
            <PFNumber></PFNumber>
            <UANNumber></UANNumber>
            <DocList>
                <listofdocs>
                    <DocumentName>abc.jpg</DocumentName>
                    <DocumentPath>base64</DocumentPath>
                </listofdocs>
            </DocList>
            <DateOfJoining>18-03-2015</DateOfJoining>
        </Employment>
    </EmploymentList>
    <AddressReferencesList>
        <ListofReferences>
            <OrganizationName>Com 1</OrganizationName>
            <AdditionalRemarks></AdditionalRemarks>
            <NameOfReferee>Ref1</NameOfReferee>
            <RefereeOccupation>SDE</RefereeOccupation>
            <RefereePhoneNumber>123456</RefereePhoneNumber>
            <RefereeEmailAddress>[email protected]</RefereeEmailAddress>
        </ListofReferences>
        <ListofReferences>
            <OrganizationName>Com 1</OrganizationName>
            <AdditionalRemarks></AdditionalRemarks>
            <NameOfReferee>Ref1</NameOfReferee>
            <RefereeOccupation>SDE</RefereeOccupation>
            <RefereePhoneNumber>123456</RefereePhoneNumber>
            <RefereeEmailAddress>[email protected]</RefereeEmailAddress>
        </ListofReferences>
    </AddressReferencesList>
    <DOB>03-08-2021</DOB>
    <DLDetails>
        <DOB>03-08-2021</DOB>
        <ApplicantName>Test</ApplicantName>
        <FatherName>Test</FatherName>
        <dl_remarks></dl_remarks>
        <UniqueIDCode>1231231</UniqueIDCode>
        <DocList>
            <listofdocs>
                <DocumentName>abc.jpg</DocumentName>
                <DocumentPath>base64</DocumentPath>
            </listofdocs>
        </DocList>
    </DLDetails>
    <PanDetails>
        <DOB>03-08-2021</DOB>
        <ApplicantName>Sunil Kumar  Yadav</ApplicantName>
        <FatherName>Sunil</FatherName>
        <pan_remarks></pan_remarks>
        <UniqueIDCode>23123131</UniqueIDCode>
        <DocList>
            <listofdocs>
                <DocumentName>abc.jpg</DocumentName>
                <DocumentPath>base64</DocumentPath>
            </listofdocs>
        </DocList>
    </PanDetails>
    <PVWDetails>
        <AddressList>
            <Address>
                <SequenceNo>0</SequenceNo>
                <AddressLine>Kharghar,navi mumbai</AddressLine>
                <City>Maharashtra-Mumbai</City>
                <State>Maharashtra</State>
                <PinCode>410210</PinCode>
                <Country>India</Country>
                <Landmark></Landmark>
                <StayFrom>01-08-2013</StayFrom>
                <StayTo>06-08-2021</StayTo>
                <IsCurrentAddress>false</IsCurrentAddress>
                <IsPermanentAddress>false</IsPermanentAddress>
                <HouseNo>Sai shradha CHS.Sector-11,</HouseNo>
                <AddressType>Current</AddressType>
                <DocList>
                    <listofdocs>
                        <DocumentName>abc.jpg</DocumentName>
                        <DocumentPath>base64</DocumentPath>
                    </listofdocs>
                </DocList>
            </Address>
        </AddressList>
        <DOB>03-08-2021</DOB>
        <FatherName>Sunil</FatherName>
        <ApplicantName>Sunil Kumar  Yadav</ApplicantName>
    </PVWDetails>
    <CreditDetail>
        <ApplicantName>Test</ApplicantName>
        <DOB>03-08-2021</DOB>
        <FatherName>Test</FatherName>
        <Gender>Male</Gender>
        <UniqueIDCode>Pan Number</UniqueIDCode>
        <EmailID>[email protected]</EmailID>
        <DocList>
            <listofdocs>
                <DocumentName>abc.jpg</DocumentName>
                <DocumentPath>base64</DocumentPath>
            </listofdocs>
        </DocList>
    </CreditDetail>
    <DrugTestPanelCheck>
        <DrugTestPanel>DrugTestPanel5</DrugTestPanel>
        <ApplicantName>Test Candidate</ApplicantName>
    </DrugTestPanelCheck>
    <GDCDetails>
        <ApplicantName>Sunil Kumar  Yadav</ApplicantName>
        <DOB>03-08-2021</DOB>
        <FatherName>Sunil</FatherName>
    </GDCDetails>
    <PassportCheckDetails>
        <NameInPassport>Sunil Kumar  Yadav</NameInPassport>
        <PassportNo>1231231</PassportNo>
        <MachineReadableZone></MachineReadableZone>
        <CandidateFirstName>Sunil</CandidateFirstName>
        <CandidateLastName>Yadav</CandidateLastName>
        <DOB>03-08-2021</DOB>
        <FatherName>Sunil</FatherName>
        <DocList>
            <listofdocs>
                <DocumentName>abc.jpg</DocumentName>
                <DocumentPath>base64</DocumentPath>
            </listofdocs>
        </DocList>
    </PassportCheckDetails>
</root>

To the below JSON payload, which as you can see has multiple array elements for even single payloads:

{
    "ClientID": "1",
    "PackageID": "650",
    "SBUID": "2187",
    "CandidateID": "456",
    "AssociateId": "789",
    "FirstName": "Meghana",
    "MiddleName": "",
    "LastName": "Rao",
    "FatherName": "Satish",
    "ContactNo": "7530001169",
    "EmailID": "[email protected]",
    "AddressHistory": {
        "Address": [
            {
                "SequenceNo": "0",
                "AddressLine": "Kharghar,navi mumbai",
                "City": "Maharashtra-Mumbai",
                "State": "Maharashtra",
                "PinCode": "410210",
                "Country": "India",
                "Landmark": "",
                "StayFrom": "01-08-2013",
                "StayTo": "06-08-2021",
                "IsCurrentAddress": false,
                "IsPermanentAddress": false,
                "HouseNo": "",
                "AddressType": "Current",
                "DocList": {
                    "listofdocs": [
                        {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }
                    ]
                }
            }
        ]
    },
    "EducationList": {
        "Education": [
            {
                "SequenceNo": "0",
                "Qualification": "",
                "Degree": "Under Graduate Degree",
                "CollegeName": "Amrutvahini College of engineering, Sangamner (Pune University)",
                "Location": "",
                "RollNumber": "123123",
                "UniversityName": "Mumbai University",
                "UniversityAddress": "",
                "PeriodFrom": "",
                "PeriodTo": "",
                "YearOfPassing": "2014",
                "Zipcode": "",
                "Percentage": "",
                "AdditionalRemarks": "10th/12th/Undergrad etc",
                "International": false,
                "Country": "",
                "DocList": {
                    "listofdocs": [
                        {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }
                    ]
                }
            }
        ]
    },
    "EmploymentList": {
        "Employment": [
            {
                "SequenceNo": "0",
                "EmployerName": "Stravis Solutions",
                "EmployerAddress": "Bangalore",
                "EmployerContactNo": "",
                "Designation": "SDE",
                "EmployeeID": "asdas",
                "FixedSalary": "0",
                "IsCurrentEmployment": false,
                "RelievingDate": "15-10-2021",
                "Zipcode": "",
                "International": false,
                "Country": "",
                "PFNumber": "",
                "UANNumber": "",
                "DocList": {
                    "listofdocs": [
                        {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }
                    ]
                },
                "DateOfJoining": "18-03-2015"
            },
            {
                "SequenceNo": "0",
                "EmployerName": "Stravis Solutions",
                "EmployerAddress": "Bangalore",
                "EmployerContactNo": "",
                "Designation": "SDE",
                "EmployeeID": "asdas",
                "FixedSalary": "0",
                "IsCurrentEmployment": false,
                "RelievingDate": "15-10-2021",
                "Zipcode": "",
                "International": false,
                "Country": "",
                "PFNumber": "",
                "UANNumber": "",
                "DocList": {
                    "listofdocs": [
                        {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }
                    ]
                },
                "DateOfJoining": "18-03-2015"
            }
        ]
    },
    "AddressReferencesList": {
        "ListofReferences": [
            {
                "OrganizationName": "Com 1",
                "AdditionalRemarks": "",
                "NameOfReferee": "Ref1",
                "RefereeOccupation": "SDE",
                "RefereePhoneNumber": "123456",
                "RefereeEmailAddress": "[email protected]"
            },
            {
                "OrganizationName": "Com 1",
                "AdditionalRemarks": "",
                "NameOfReferee": "Ref2",
                "RefereeOccupation": "SDE",
                "RefereePhoneNumber": "123456",
                "RefereeEmailAddress": "[email protected]"
            }
        ]
    },
    "DOB": "03-08-2021",
    "DLDetails": {
        "DOB": "03-08-2021",
        "ApplicantName": "Test",
        "FatherName": "Test",
        "UniqueIDCode": "1231231",
        "DocList": {
            "listofdocs": [
                  {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }
            ]
        }
    },
    "PanDetails": {
        "DOB": "03-08-2021",
        "ApplicantName": "Sunil Kumar  Yadav",
        "FatherName": "Sunil",
        "UniqueIDCode": "23123131",
        "DocList": {
            "listofdocs": [
                {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                   }
            ]
        }
    },
    "PVWDetails": {
        "AddressList": {
            "Address": [
                {
                    "SequenceNo": "0",
                    "AddressLine": "Kharghar,navi mumbai",
                    "City": "Maharashtra-Mumbai",
                    "State": "Maharashtra",
                    "PinCode": "410210",
                    "Country": "India",
                    "Landmark": "",
                    "StayFrom": "01-08-2013",
                    "StayTo": "06-08-2021",
                    "IsCurrentAddress": false,
                    "IsPermanentAddress": false,
                    "HouseNo": "Sai shradha CHS.Sector-11,",
                    "AddressType": "Current",
                    "DocList": {
                        "listofdocs": [
                            {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }
                        ]
                    }
                }
            ]
        },
        "DOB": "03-08-2021",
        "FatherName": "Sunil",
        "ApplicantName": "Sunil Kumar  Yadav"
    },
    "CreditDetail": {
        "ApplicantName": "Test",
        "DOB": "03-08-2021",
        "FatherName": "Test",
        "Gender": "Male",
        "UniqueIDCode": "Pan Number",
        "EmailID": "[email protected]",
        "DocList": {
            "listofdocs": [
                {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }

            ]
        }
    },
    "PassportCheckDetails": {
        "NameInPassport": "Sunil Kumar  Yadav",
        "PassportNo": "1231231",
        "MachineReadableZone": "",
        "CandidateFirstName": "Sunil",
        "CandidateLastName": "Yadav",
        "DOB": "03-08-2021",
        "FatherName": "Sunil",
        "DocList": {
            "listofdocs": [
                {
                                    "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"                        
                         }

            ]
        }
    }
}

As you can see, there is an array created for every part of the data. How can I achieve this with XSLT?

Whatever code i have tried with so far, the converted JSON has not had any arrays barring cases where there are multiple records under a root.

I have tried variations of the following code:

    <?xml version="1.0" encoding="UTF-8"?>
     <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://use your namespace">
    <xsl:output method="text"/>
    <xsl:template match="/ns0:Account_Resp">{
        <xsl:apply-templates select="*"/> }
    </xsl:template>
    
    <!-- Object or Element Property-->
    <xsl:template match="*">
    
        "<xsl:value-of select="name()"/>" : <xsl:call-template name="Properties"/>
        
    
    </xsl:template>
    
    
    <!-- Array Element -->
    <xsl:template match="*" mode="ArrayElement">
        <xsl:call-template name="Properties"/>
    </xsl:template>
    
    
    <!-- Object Properties -->
    <xsl:template name="Properties">
        <xsl:variable name="childName" select="name(*[1])"/>
        <xsl:choose>
            <xsl:when test="not(*|@*)">"<xsl:value-of select="."/>"</xsl:when>
            <xsl:when test="count(*[name()=$childName]) > 1">{ "<xsl:value-of select="$childName"/>" :[<xsl:apply-templates select="*" mode="ArrayElement"/>] }</xsl:when>
            <xsl:otherwise>{
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates select="*"/>
    }</xsl:otherwise>
        </xsl:choose>
        <xsl:if test="following-sibling::*">,</xsl:if>
    </xsl:template>
    
    
    <!-- Attribute Property -->
    <xsl:template `enter code here`match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
    </xsl:template>
    </xsl:stylesheet>

And received the following output - in which you can see that for single payloads, an array is not getting created:

{
    "ClientID" : "1",
    "PackageID" : "650",
    "SBUID" : "2187",
    "CandidateID" : "456",
    "AssociateId" : "789",
    "FirstName" : "Meghana",
    "MiddleName" : "",
    "LastName" : "Rao",
    "FatherName" : "Satish",
    "ContactNo" : "7530001169",
    "EmailID" : "[email protected]",

    "AddressHistory" : { "Address" :[{
    "SequenceNo" : "0",
    "AddressLine" : "Kharghar,navi mumbai",
    "City" : "Maharashtra-Mumbai",
    "State" : "Maharashtra",
    "PinCode" : "410210",
    "Country" : "India",
    "Landmark" : "",
    "StayFrom" : "01-08-2013",
    "StayTo" : "06-08-2021",
    "IsCurrentAddress" : "false",
    "IsPermanentAddress" : "false",
    "HouseNo" : "",
    "AddressType" : "Current",
    "DocList" : { "listofdocs" :[{
    "DocumentName" : "abc.jpg",
    "DocumentPath" : "base64"
}] }
},{
    "SequenceNo" : "1",
    "AddressLine" : "Kharghar,navi mumbai",
    "City" : "Maharashtra-Mumbai",
    "State" : "Maharashtra",
    "PinCode" : "410210",
    "Country" : "India",
    "Landmark" : "",
    "StayFrom" : "01-08-2013",
    "StayTo" : "06-08-2021",
    "IsCurrentAddress" : "false",
    "IsPermanentAddress" : "false",
    "HouseNo" : "",
    "AddressType" : "Current",
    "DocList" : { "listofdocs" :[{
    "DocumentName" : "def.jpg",
    "DocumentPath" : "base64"
}] }
}] },

    "EducationList" : {
    "Education" : {
    "SequenceNo" : "0",
    "Qualification" : "",
    "Degree" : "Under Graduate Degree",
    "CollegeName" : "Amrutvahini College of engineering, Sangamner (Pune University)",
    "Location" : "",
    "RollNumber" : "123123",
    "UniversityName" : "Mumbai University",
    "UniversityAddress" : "",
    "PeriodFrom" : "",
    "PeriodTo" : "",
    "YearOfPassing" : "2014",
    "Percentage" : "",
    "AdditionalRemarks" : "10th/12th/Undergrad etc",
    "International" : "false",
    "Country" : "",
    "DocList" : { "listofdocs" :[{
    "DocumentName" : "def.jpg",
    "DocumentPath" : "base64"
}] }
}
},
    "EmploymentList" : { "Employment" :[{
    "SequenceNo" : "0",
    "EmployerName" : "Stravis Solutions",
    "EmployerAddress" : "Bangalore",
    "EmployerContactNo" : "",
    "Designation" : "SDE",
    "EmployeeID" : "asdas",
    "FixedSalary" : "0",
    "IsCurrentEmployment" : "false",
    "RelievingDate" : "15-10-2021",
    "Zipcode" : "",
    "International" : "false",
    "Country" : "",
    "PFNumber" : "",
    "UANNumber" : "",
    "DocList" : {
    "listofdocs" : {
    "DocumentName" : "abc.jpg",
    "DocumentPath" : "base64"
}
},
    "DateOfJoining" : "18-03-2015"
},{
    "SequenceNo" : "1",
    "EmployerName" : "Stravis Solutions",
    "EmployerAddress" : "Bangalore",
    "EmployerContactNo" : "",
    "Designation" : "SDE",
    "EmployeeID" : "asdas",
    "FixedSalary" : "0",
    "IsCurrentEmployment" : "false",
    "RelievingDate" : "15-10-2021",
    "Zipcode" : "",
    "International" : "false",
    "Country" : "",
    "PFNumber" : "",
    "UANNumber" : "",
    "DocList" : {
    "listofdocs" : {
    "DocumentName" : "def.jpg",
    "DocumentPath" : "base64"
}
},
    "DateOfJoining" : "18-03-2015"
}] },

    "AddressReferencesList" : { "ListofReferences" :[{
    "OrganizationName" : "Com 1",
    "AdditionalRemarks" : "",
    "NameOfReferee" : "Ref1",
    "RefereeOccupation" : "SDE",
    "RefereePhoneNumber" : "123456",
    "RefereeEmailAddress" : "[email protected]"
},{
    "OrganizationName" : "Com 1",
    "AdditionalRemarks" : "",
    "NameOfReferee" : "Ref2",
    "RefereeOccupation" : "SDE",
    "RefereePhoneNumber" : "123456",
    "RefereeEmailAddress" : "[email protected]"
}] },
    "DOB" : "03-08-2021",
    "DLDetails" : {
    "DOB" : "03-08-2021",
    "ApplicantName" : "Test",
    "FatherName" : "Test",
    "UniqueIDCode" : "1231231",
    "DocList" : {
    "listofdocs" : {
    "DocumentName" : "abc.jpg",
    "DocumentPath" : "base64"
}
}
},
    "PanDetails" : {
    "DOB" : "03-08-2021",
    "ApplicantName" : "Sunil Kumar  Yadav",
    "FatherName" : "Sunil",
    "UniqueIDCode" : "23123131",
    "DocList" : {
    "listofdocs" : {
    "DocumentName" : "abc.jpg",
    "DocumentPath" : "base64"
}
}
},
    "PVWDetails" : {
    "AddressList" : {
    "Address" : {
    "SequenceNo" : "0",
    "AddressLine" : "Kharghar,navi mumbai",
    "City" : "Maharashtra-Mumbai",
    "State" : "Maharashtra",
    "PinCode" : "410210",
    "Country" : "India",
    "Landmark" : "",
    "StayFrom" : "01-08-2013",
    "StayTo" : "06-08-2021",
    "IsCurrentAddress" : "false",
    "IsPermanentAddress" : "false",
    "HouseNo" : "Sai shradha CHS.Sector-11,",
    "AddressType" : "Current"
}
},
    "DOB" : "03-08-2021",
    "FatherName" : "Sunil",
    "ApplicantName" : "Sunil Kumar  Yadav"
},
    "CreditDetail" : {
    "ApplicantName" : "Test",
    "DOB" : "03-08-2021",
    "FatherName" : "Test",
    "Gender" : "Male",
    "UniqueIDCode" : "Pan Number",
    "EmailID" : "[email protected]",
    "DocList" : {
    "listofdocs" : {
    "DocumentName" : "abc.jpg",
    "DocumentPath" : "base64"
}
}
},        "DrugTestPanelCheck" : {
    "DrugTestPanel" : "DrugTestPanel5",
    "ApplicantName" : "Test Candidate"
},
    "GDCDetails" : {
    "ApplicantName" : "Sunil Kumar  Yadav",
    "DOB" : "03-08-2021",
    "FatherName" : "Sunil"
},
    "PassportCheckDetails" : {
    "NameInPassport" : "Sunil Kumar  Yadav",
    "PassportNo" : "1231231",
    "MachineReadableZone" : "",
    "CandidateFirstName" : "Sunil",
    "CandidateLastName" : "Yadav",
    "DOB" : "03-08-2021",
    "FatherName" : "Sunil",
    "DocList" : {
    "listofdocs" : {
    "DocumentName" : "abc.jpg",
    "DocumentPath" : "base64"
}
}
}
}

Really need some help on this. Thanks

3

There are 3 answers

0
Heiko Theißen On

In order to determine which XML elements can occur with cardinality 0..*, you look only at the actual cardinality in the payload by testing whether count(*[name()=$childName]) > 1. By this, you miss the fact that the <EducationList> is allowed to contain more than one <Education> (even if it contains only one in this particular payload instance).

A clean solution would require you to look at the XML schema (in the WSDL document, probably). But in this case, the following heuristics might suffice: If an element name ends with List, it contains children with cardinality 0..*. Therefore, replace the test count(*[name()=$childName]) > 1 with

substring(name(), string-length(name()) - 3, 4) = 'List'
2
jpseng On

With the YAML processor mikefarah/yq, you can convert XML to JSON and make some custom adoptions to the conversion:

yq --input-format xml --output-format json '
with(.root;
     .AddressHistory.Address                 |= select(type == "!!map") |= [.] |
     .EducationList.Education                |= select(type == "!!map") |= [.] |
     .EmploymentList.Employment              |= select(type == "!!map") |= [.] |
     .AddressReferencesList.ListofReferences |= select(type == "!!map") |= [.] |
     .PVWDetails.AddressList.Address         |= select(type == "!!map") |= [.]
    )
   ' input.xml

For given paths the update operator |= wraps an object (select(type == "!!map")) into an array ([.]). Add all elements that should be an array to the code.


With kislyuk/xq, you can solve it this way:

ARRAY_PATHS='
[
  "root.AddressHistory.Address",
  "root.EducationList.Education",
  "root.EmploymentList.Employment",
  "root.AddressReferencesList.ListofReferences",
  "root.PVWDetails.AddressList.Address"
]
'

xq --argjson paths "$ARRAY_PATHS" '
  . as $input
  | reduce ($paths
            | map(split(".")                                              # split given paths by "."
                  | . as $p
                  | select($input | getpath($p) | type == "object")))[]   # process only objects at the given paths (ignore arrays)
           as $path
           (.; setpath($path; [getpath($path)]))                          # wrap objects at the given paths in an array
 ' input.xml

All given paths are checked if the value is an object: select($input | getpath($p) | type == "object"). Objects are wrapped into an array setpath($path; [getpath($path)]). This solution is more generic and failsafe, if a given path is missing in the input.


Output (both versions)

{
  "root": {
    "ClientID": "1",
    "PackageID": "650",
    "SBUID": "2187",
    "CandidateID": "456",
    "AssociateId": "789",
    "FirstName": "Meghana",
    "MiddleName": null,
    "LastName": "Rao",
    "FatherName": "Satish",
    "ContactNo": "7530001169",
    "EmailID": "[email protected]",
    "AddressHistory": {
      "Address": [
        {
          "SequenceNo": "0",
          "AddressLine": "Kharghar,navi mumbai",
          "City": "Maharashtra-Mumbai",
          "State": "Maharashtra",
          "PinCode": "410210",
          "Country": "India",
          "Landmark": null,
          "StayFrom": "01-08-2013",
          "StayTo": "06-08-2021",
          "IsCurrentAddress": "false",
          "IsPermanentAddress": "false",
          "HouseNo": null,
          "AddressType": "Current",
          "DocList": {
            "listofdocs": {
              "DocumentName": "abc.jpg",
              "DocumentPath": "base64"
            }
          }
        }
      ]
    },
    "EducationList": {
      "Education": [
        {
          "SequenceNo": "0",
          "Qualification": null,
          "Degree": "Under Graduate Degree",
          "CollegeName": "Amrutvahini College of engineering, Sangamner (Pune University)",
          "Location": null,
          "RollNumber": "123123",
          "UniversityName": "Mumbai University",
          "UniversityAddress": null,
          "PeriodFrom": null,
          "PeriodTo": null,
          "YearOfPassing": "2014",
          "Zipcode": null,
          "Percentage": null,
          "AdditionalRemarks": "10th/12th/Undergrad etc",
          "International": "false",
          "Country": null,
          "DocList": {
            "listofdocs": {
              "DocumentName": "abc.jpg",
              "DocumentPath": "base64"
            }
          }
        }
      ]
    },
    "EmploymentList": {
      "Employment": [
        {
          "SequenceNo": "0",
          "EmployerName": "Stravis Solutions",
          "EmployerAddress": "Bangalore",
          "EmployerContactNo": null,
          "Designation": "SDE",
          "EmployeeID": "asdas",
          "FixedSalary": "0",
          "IsCurrentEmployment": "false",
          "RelievingDate": "15-10-2021",
          "State": null,
          "City": null,
          "Zipcode": null,
          "International": "false",
          "Country": null,
          "PFNumber": null,
          "UANNumber": null,
          "DocList": {
            "listofdocs": {
              "DocumentName": "abc.jpg",
              "DocumentPath": "base64"
            }
          },
          "DateOfJoining": "18-03-2015"
        },
        {
          "SequenceNo": "0",
          "EmployerName": "Stravis Solutions",
          "EmployerAddress": "Bangalore",
          "EmployerContactNo": null,
          "Designation": "SDE",
          "EmployeeID": "asdas",
          "FixedSalary": "0",
          "IsCurrentEmployment": "false",
          "RelievingDate": "15-10-2021",
          "International": "false",
          "Country": null,
          "PFNumber": null,
          "UANNumber": null,
          "DocList": {
            "listofdocs": {
              "DocumentName": "abc.jpg",
              "DocumentPath": "base64"
            }
          },
          "DateOfJoining": "18-03-2015"
        }
      ]
    },
    "AddressReferencesList": {
      "ListofReferences": [
        {
          "OrganizationName": "Com 1",
          "AdditionalRemarks": null,
          "NameOfReferee": "Ref1",
          "RefereeOccupation": "SDE",
          "RefereePhoneNumber": "123456",
          "RefereeEmailAddress": "[email protected]"
        },
        {
          "OrganizationName": "Com 1",
          "AdditionalRemarks": null,
          "NameOfReferee": "Ref1",
          "RefereeOccupation": "SDE",
          "RefereePhoneNumber": "123456",
          "RefereeEmailAddress": "[email protected]"
        }
      ]
    },
    "DOB": "03-08-2021",
    "DLDetails": {
      "DOB": "03-08-2021",
      "ApplicantName": "Test",
      "FatherName": "Test",
      "dl_remarks": null,
      "UniqueIDCode": "1231231",
      "DocList": {
        "listofdocs": {
          "DocumentName": "abc.jpg",
          "DocumentPath": "base64"
        }
      }
    },
    "PanDetails": {
      "DOB": "03-08-2021",
      "ApplicantName": "Sunil Kumar  Yadav",
      "FatherName": "Sunil",
      "pan_remarks": null,
      "UniqueIDCode": "23123131",
      "DocList": {
        "listofdocs": {
          "DocumentName": "abc.jpg",
          "DocumentPath": "base64"
        }
      }
    },
    "PVWDetails": {
      "AddressList": {
        "Address": [
          {
            "SequenceNo": "0",
            "AddressLine": "Kharghar,navi mumbai",
            "City": "Maharashtra-Mumbai",
            "State": "Maharashtra",
            "PinCode": "410210",
            "Country": "India",
            "Landmark": null,
            "StayFrom": "01-08-2013",
            "StayTo": "06-08-2021",
            "IsCurrentAddress": "false",
            "IsPermanentAddress": "false",
            "HouseNo": "Sai shradha CHS.Sector-11,",
            "AddressType": "Current",
            "DocList": {
              "listofdocs": {
                "DocumentName": "abc.jpg",
                "DocumentPath": "base64"
              }
            }
          }
        ]
      },
      "DOB": "03-08-2021",
      "FatherName": "Sunil",
      "ApplicantName": "Sunil Kumar  Yadav"
    },
    "CreditDetail": {
      "ApplicantName": "Test",
      "DOB": "03-08-2021",
      "FatherName": "Test",
      "Gender": "Male",
      "UniqueIDCode": "Pan Number",
      "EmailID": "[email protected]",
      "DocList": {
        "listofdocs": {
          "DocumentName": "abc.jpg",
          "DocumentPath": "base64"
        }
      }
    },
    "DrugTestPanelCheck": {
      "DrugTestPanel": "DrugTestPanel5",
      "ApplicantName": "Test Candidate"
    },
    "GDCDetails": {
      "ApplicantName": "Sunil Kumar  Yadav",
      "DOB": "03-08-2021",
      "FatherName": "Sunil"
    },
    "PassportCheckDetails": {
      "NameInPassport": "Sunil Kumar  Yadav",
      "PassportNo": "1231231",
      "MachineReadableZone": null,
      "CandidateFirstName": "Sunil",
      "CandidateLastName": "Yadav",
      "DOB": "03-08-2021",
      "FatherName": "Sunil",
      "DocList": {
        "listofdocs": {
          "DocumentName": "abc.jpg",
          "DocumentPath": "base64"
        }
      }
    }
  }
}
0
pgfearo On

The standard xml-to-json XSLT 3.0 function can meet your requirement. The complexity lies in establishing the transform rules for when to use JSON maps and arrays.

I inferred the transform rules from the supplied input XML and output JSON. These rules may need adjustment to cover cases not tested by your sample. Here's the main xsl:template instruction:

<xsl:template match="*[*]" mode="outer">
<xsl:param name="key" as="xs:string?"/>
<xsl:variable name="distinctChildNames" as="xs:string*" select="*!name() => distinct-values()"/>
<xsl:choose>
  <xsl:when test="count($distinctChildNames) gt 1 and exists($key)">
    <array>
      <xsl:sequence select="fn:keyAttribute(name())"/>
      <map>
        <xsl:apply-templates select="*" mode="outer">
          <xsl:with-param name="key" select="name()"/>
        </xsl:apply-templates>
      </map>
    </array>
  </xsl:when>
  <xsl:when test="count(*) gt 1 and count($distinctChildNames) eq 1">
    <map>
      <xsl:sequence select="fn:keyAttribute(name())"/>
      <array key="{name(*[1])}">
        <xsl:for-each select="*">
          <map>
            <xsl:apply-templates select="*" mode="outer"/>
          </map>
        </xsl:for-each>
      </array>
    </map>
  </xsl:when>
  <xsl:otherwise>
    <map>
      <xsl:sequence select="fn:keyAttribute(name())"/>      
      <xsl:apply-templates select="*" mode="outer">
        <xsl:with-param name="key" select="name()"/>
      </xsl:apply-templates>  
    </map>
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

The JSON output:

    {
    "ClientID": "1",
    "PackageID": "650",
    "SBUID": "2187",
    "CandidateID": "456",
    "AssociateId": "789",
    "FirstName": "Meghana",
    "MiddleName": "",
    "LastName": "Rao",
    "FatherName": "Satish",
    "ContactNo": "7530001169",
    "EmailID": "[email protected]",
    "AddressHistory": {
        "Address": [
            {
                "SequenceNo": "0",
                "AddressLine": "Kharghar,navi mumbai",
                "City": "Maharashtra-Mumbai",
                "State": "Maharashtra",
                "PinCode": "410210",
                "Country": "India",
                "Landmark": "",
                "StayFrom": "01-08-2013",
                "StayTo": "06-08-2021",
                "IsCurrentAddress": false,
                "IsPermanentAddress": false,
                "HouseNo": "",
                "AddressType": "Current",
                "DocList": {
                    "listofdocs": [
                        {
                            "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"
                        }
                    ]
                }
            }
        ]
    },
    "EducationList": {
        "Education": [
            {
                "SequenceNo": "0",
                "Qualification": "",
                "Degree": "Under Graduate Degree",
                "CollegeName": "Amrutvahini College of engineering, Sangamner (Pune University)",
                "Location": "",
                "RollNumber": "123123",
                "UniversityName": "Mumbai University",
                "UniversityAddress": "",
                "PeriodFrom": "",
                "PeriodTo": "",
                "YearOfPassing": "2014",
                "Zipcode": "",
                "Percentage": "",
                "AdditionalRemarks": "10th\/12th\/Undergrad etc",
                "International": false,
                "Country": "",
                "DocList": {
                    "listofdocs": [
                        {
                            "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"
                        }
                    ]
                }
            }
        ]
    },
    "EmploymentList": {
        "Employment": [
            {
                "SequenceNo": "0",
                "EmployerName": "Stravis Solutions",
                "EmployerAddress": "Bangalore",
                "EmployerContactNo": "",
                "Designation": "SDE",
                "EmployeeID": "asdas",
                "FixedSalary": "0",
                "IsCurrentEmployment": false,
                "RelievingDate": "15-10-2021",
                "State": "",
                "City": "",
                "Zipcode": "",
                "International": false,
                "Country": "",
                "PFNumber": "",
                "UANNumber": "",
                "DocList": {
                    "listofdocs": [
                        {
                            "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"
                        }
                    ]
                },
                "DateOfJoining": "18-03-2015"
            },
            {
                "SequenceNo": "0",
                "EmployerName": "Stravis Solutions",
                "EmployerAddress": "Bangalore",
                "EmployerContactNo": "",
                "Designation": "SDE",
                "EmployeeID": "asdas",
                "FixedSalary": "0",
                "IsCurrentEmployment": false,
                "RelievingDate": "15-10-2021",
                "International": false,
                "Country": "",
                "PFNumber": "",
                "UANNumber": "",
                "DocList": {
                    "listofdocs": [
                        {
                            "DocumentName": "abc.jpg",
                            "DocumentPath": "base64"
                        }
                    ]
                },
                "DateOfJoining": "18-03-2015"
            }
        ]
    },
    "AddressReferencesList": {
        "ListofReferences": [
            {
                "OrganizationName": "Com 1",
                "AdditionalRemarks": "",
                "NameOfReferee": "Ref1",
                "RefereeOccupation": "SDE",
                "RefereePhoneNumber": "123456",
                "RefereeEmailAddress": "[email protected]"
            },
            {
                "OrganizationName": "Com 1",
                "AdditionalRemarks": "",
                "NameOfReferee": "Ref1",
                "RefereeOccupation": "SDE",
                "RefereePhoneNumber": "123456",
                "RefereeEmailAddress": "[email protected]"
            }
        ]
    },
    "DOB": "03-08-2021",
    "DLDetails": {
        "DOB": "03-08-2021",
        "ApplicantName": "Test",
        "FatherName": "Test",
        "dl_remarks": "",
        "UniqueIDCode": "1231231",
        "DocList": {
            "listofdocs": [
                {
                    "DocumentName": "abc.jpg",
                    "DocumentPath": "base64"
                }
            ]
        }
    },
    "PanDetails": {
        "DOB": "03-08-2021",
        "ApplicantName": "Sunil Kumar  Yadav",
        "FatherName": "Sunil",
        "pan_remarks": "",
        "UniqueIDCode": "23123131",
        "DocList": {
            "listofdocs": [
                {
                    "DocumentName": "abc.jpg",
                    "DocumentPath": "base64"
                }
            ]
        }
    },
    "PVWDetails": {
        "AddressList": {
            "Address": [
                {
                    "SequenceNo": "0",
                    "AddressLine": "Kharghar,navi mumbai",
                    "City": "Maharashtra-Mumbai",
                    "State": "Maharashtra",
                    "PinCode": "410210",
                    "Country": "India",
                    "Landmark": "",
                    "StayFrom": "01-08-2013",
                    "StayTo": "06-08-2021",
                    "IsCurrentAddress": false,
                    "IsPermanentAddress": false,
                    "HouseNo": "Sai shradha CHS.Sector-11,",
                    "AddressType": "Current",
                    "DocList": {
                        "listofdocs": [
                            {
                                "DocumentName": "abc.jpg",
                                "DocumentPath": "base64"
                            }
                        ]
                    }
                }
            ]
        },
        "DOB": "03-08-2021",
        "FatherName": "Sunil",
        "ApplicantName": "Sunil Kumar  Yadav"
    },
    "CreditDetail": {
        "ApplicantName": "Test",
        "DOB": "03-08-2021",
        "FatherName": "Test",
        "Gender": "Male",
        "UniqueIDCode": "Pan Number",
        "EmailID": "[email protected]",
        "DocList": {
            "listofdocs": [
                {
                    "DocumentName": "abc.jpg",
                    "DocumentPath": "base64"
                }
            ]
        }
    },
    "DrugTestPanelCheck": {
        "DrugTestPanel": "DrugTestPanel5",
        "ApplicantName": "Test Candidate"
    },
    "GDCDetails": {
        "ApplicantName": "Sunil Kumar  Yadav",
        "DOB": "03-08-2021",
        "FatherName": "Sunil"
    },
    "PassportCheckDetails": {
        "NameInPassport": "Sunil Kumar  Yadav",
        "PassportNo": "1231231",
        "MachineReadableZone": "",
        "CandidateFirstName": "Sunil",
        "CandidateLastName": "Yadav",
        "DOB": "03-08-2021",
        "FatherName": "Sunil",
        "DocList": {
            "listofdocs": [
                {
                    "DocumentName": "abc.jpg",
                    "DocumentPath": "base64"
                }
            ]
        }
    }
}

There are minor differences in the result:

  1. The '/' character is escaped to \/ in the JSON output
  2. JSON properties transformed from empty XML elements: the XSLT here always keeps the property and sets the value to an empty string

Here's the full XSLT used:

<?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"
                xmlns:fn="com.example.functions"
                xmlns="http://www.w3.org/2005/xpath-functions"
                expand-text="yes"
                version="3.0">
  
  <xsl:output method="text" indent="yes"/>
  <xsl:mode on-no-match="shallow-copy"/>
  <xsl:mode name="outer" on-no-match="shallow-copy"/>
  
  <xsl:template match="/*">
    <xsl:variable name="result" as="node()*">
      <map>
        <xsl:apply-templates select="*" mode="outer"/>
      </map>
    </xsl:variable>
    <xsl:sequence select="xml-to-json($result)"/>
  </xsl:template>
  
  <xsl:template match="*[*]" mode="outer">
    <xsl:param name="key" as="xs:string?"/>
    <xsl:variable name="distinctChildNames" as="xs:string*" select="*!name() => distinct-values()"/>
    <xsl:choose>
      <xsl:when test="count($distinctChildNames) gt 1 and exists($key)">
        <array>
          <xsl:sequence select="fn:keyAttribute(name())"/>
          <map>
            <xsl:apply-templates select="*" mode="outer">
              <xsl:with-param name="key" select="name()"/>
            </xsl:apply-templates>
          </map>
        </array>
      </xsl:when>
      <xsl:when test="count(*) gt 1 and count($distinctChildNames) eq 1">
        <map>
          <xsl:sequence select="fn:keyAttribute(name())"/>
          <array key="{name(*[1])}">
            <xsl:for-each select="*">
              <map>
                <xsl:apply-templates select="*" mode="outer"/>
              </map>
            </xsl:for-each>
          </array>
        </map>
      </xsl:when>
      <xsl:otherwise>
        <map>
          <xsl:sequence select="fn:keyAttribute(name())"/>      
          <xsl:apply-templates select="*" mode="outer">
            <xsl:with-param name="key" select="name()"/>
          </xsl:apply-templates>  
        </map>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="*[empty(*) and exists(text())]" mode="outer">
    <xsl:apply-templates select="node()" mode="outer">
      <xsl:with-param name="key" select="name()"/>
    </xsl:apply-templates>
  </xsl:template>
  
  <xsl:template match="*[empty(*) and empty(text())]" mode="outer">
    <string key="{name()}"/>
  </xsl:template>
  
  <xsl:template match="text()[. = ('true', 'false')]" mode="outer">
    <xsl:param name="key" as="xs:string?"/>
    <boolean key="{$key}">{.}</boolean>
  </xsl:template>
  
  <xsl:template match="text()" mode="outer">
    <xsl:param name="key" as="xs:string?"/>
    <xsl:if test="exists($key)">
      <string key="{$key}">{.}</string>
    </xsl:if>
  </xsl:template>
  
  <xsl:function name="fn:keyAttribute" as="attribute()?">
    <xsl:param name="key" as="xs:string?"/>
    <xsl:if test="$key">
      <xsl:attribute name="key" select="$key"/>
    </xsl:if>
  </xsl:function>
  
</xsl:stylesheet>