unable to convert Xml To Json format using xslt

Hi All,

I have a usecase where to send xml request and get the json response using "xsl transform":

Xslt code is:(XSL-Tranform.xsl)->

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/">{     <xsl:apply-templates select="*"/>} </xsl:template>
<!-- Object or Element Property-->
<xsl:template match="*">     "<xsl:value-of select="name()"/>" :<xsl:call-template name="Properties">         <xsl:with-param name="parent" select="'Yes'"></xsl:with-param>
    </xsl:call-template> </xsl:template> <!-- Array Element -->
<xsl:template match="*" mode="ArrayElement">
    <xsl:call-template name="Properties"/> </xsl:template>
<!-- Object Properties -->
<xsl:template name="Properties">     <xsl:param name="parent"></xsl:param>
    <xsl:variable name="childName" select="name(*[1])"/>     <xsl:choose>           
        <xsl:when test="not(*|@*)"><xsl:choose><xsl:when test="$parent='Yes'"> <xsl:text>"</xsl:text><xsl:value-of select="."/><xsl:text>"</xsl:text></xsl:when>                 <xsl:otherwise>"<xsl:value-of select="name()"/>":"<xsl:value-of  select="."/>"</xsl:otherwise>
            </xsl:choose>           
        </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 match="@*">"<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
</xsl:template> </xsl:stylesheet>

xml input data(Request) is:

<?xml version="1.0" encoding="UTF-8"?>
<VisitorsN> <VisitorA>
 <first_name>Gov</first_name>  <middle_name>Kr</middle_name>
 <Last_name>Verma</Last_name>
 <house_number>15</house_number>
 <road_namee>ratu road</road_namee>
 <pincode>239809709</pincode>
</VisitorA>
 <VisitorB>
 <first_name>Amit</first_name>  <Last_name>Singh</Last_name> <house_number></house_number> <road_namee>Harmu</road_namee>  <pincode>398097692</pincode>
 </VisitorB>
 </VisitorsN>

Output data(response)is:

<?xml version="1.0" encoding="UTF-8"?>{     "VisitorsN" :{
    "VisitorA" :{
    "first_name" :"Govind",     
    "middle_name" :"Kr",     
    "Last_name" :"Verma",   
    "house_number" :"15",
    "road_namee" :"ratu road",    
    "pincode" :"239809709"
            },
     "VisitorB" :{
    "first_name" :"Amit",
    "Last_name" :"Singh",     
    "house_number" :"",     
    "road_namee" :"Harmu",     
    "pincode" :"398097692"
            }
            }} 

But i want output (response) as:

<?xml version="1.0" encoding="UTF-8"?>
{ "VisitorsN" :
{ "VisitorA" :{"name" : "Govind Kr Verma",
address : 15,raturoad 239809709}, 
"VisitorB" :
{"name" : "Amit Singh",
address : Harmu 398097692}
}}

Could someone please help me?

Any Advice what i'm doing wrong here?

Thanks and Regards

Govind Verma

@Anil Sagar @ Google, @Dino-at-Google,@Robert Johnson,@Brendan,@Siddharth Barahalikar,

Solved Solved
0 2 4,439
1 ACCEPTED SOLUTION

The XSLT you're using is a simple XML to JSON converter that does not manipulate the content or names of elements.

In your desired output, you want "name" to be the result of concatenating "first_name", "middle_name" and "last_name", and similarly you want "address" to be the concatenation of other elements.

I suggest you first run an XSL transformation that generates an XML with the desired elements (name and address) and then apply your XSL transformation, or better still use the XML to JSON policy which generates the same result, and it's easier to understand and maintain.

After applying this XSL to your original XML:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<VisitorsN>
<xsl:for-each select="/child::*/child::*">
<xsl:variable name="curElementName" select="name()"/>
<xsl:element name="{$curElementName}">
<name>
<xsl:value-of select="normalize-space(concat(./first_name,' ', ./middle_name,' ', ./Last_name))"/>
</name>
<address>
<xsl:value-of select="normalize-space(concat(./house_number,', ',./road_namee,' ',./pincode))"/>
</address>
</xsl:element>
</xsl:for-each>
</VisitorsN>
</xsl:template>
</xsl:stylesheet>

you get this XML:

<?xml version="1.0" encoding="UTF-8"?>
<VisitorsN>
<VisitorA>
<name>Gov Kr Verma</name>
<address>15, ratu road 239809709</address>
</VisitorA>
<VisitorB>
<name>Amit Singh</name>
<address>, Harmu 398097692</address>
</VisitorB>
</VisitorsN>

You can then apply this XML2JSON policy (assuming the transformed XML is in the request):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLToJSON async="false" continueOnError="false" enabled="true" name="XML-to-JSON-1">
    <DisplayName>XML to JSON-1</DisplayName>
    <Properties/>
    <Format>yahoo</Format>
    <OutputVariable>jsonVar</OutputVariable>
    <Source>request.content</Source>
</XMLToJSON>

to obtain the desired JSON output in a variable named jsonVar:

{
"VisitorsN": {
"VisitorA": {
"name": "Gov Kr Verma",
"address": "15, ratu road 239809709"
},
"VisitorB": {
"name": "Amit Singh",
"address": ", Harmu 398097692"
}
}
}

View solution in original post

2 REPLIES 2

The XSLT you're using is a simple XML to JSON converter that does not manipulate the content or names of elements.

In your desired output, you want "name" to be the result of concatenating "first_name", "middle_name" and "last_name", and similarly you want "address" to be the concatenation of other elements.

I suggest you first run an XSL transformation that generates an XML with the desired elements (name and address) and then apply your XSL transformation, or better still use the XML to JSON policy which generates the same result, and it's easier to understand and maintain.

After applying this XSL to your original XML:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<VisitorsN>
<xsl:for-each select="/child::*/child::*">
<xsl:variable name="curElementName" select="name()"/>
<xsl:element name="{$curElementName}">
<name>
<xsl:value-of select="normalize-space(concat(./first_name,' ', ./middle_name,' ', ./Last_name))"/>
</name>
<address>
<xsl:value-of select="normalize-space(concat(./house_number,', ',./road_namee,' ',./pincode))"/>
</address>
</xsl:element>
</xsl:for-each>
</VisitorsN>
</xsl:template>
</xsl:stylesheet>

you get this XML:

<?xml version="1.0" encoding="UTF-8"?>
<VisitorsN>
<VisitorA>
<name>Gov Kr Verma</name>
<address>15, ratu road 239809709</address>
</VisitorA>
<VisitorB>
<name>Amit Singh</name>
<address>, Harmu 398097692</address>
</VisitorB>
</VisitorsN>

You can then apply this XML2JSON policy (assuming the transformed XML is in the request):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XMLToJSON async="false" continueOnError="false" enabled="true" name="XML-to-JSON-1">
    <DisplayName>XML to JSON-1</DisplayName>
    <Properties/>
    <Format>yahoo</Format>
    <OutputVariable>jsonVar</OutputVariable>
    <Source>request.content</Source>
</XMLToJSON>

to obtain the desired JSON output in a variable named jsonVar:

{
"VisitorsN": {
"VisitorA": {
"name": "Gov Kr Verma",
"address": "15, ratu road 239809709"
},
"VisitorB": {
"name": "Amit Singh",
"address": ", Harmu 398097692"
}
}
}