I am working on a proxy to convert Soap Service to Rest API that would allow JSON payload. It's using JSON to XML polity to convert JSON payload to XML. It works fine if incoming JSON elements are in sequence specified in wsdl but if JSON elements are not in order, call to soap service fails since it expects XML elements in specific order according to WSDL.
How can i reorder XML generated from JSON to XML policy according to the schema?
Appriciate any help.
Thanks.
Answer by Dino
·
Jun 02, 2017 at 08:59 PM
You can apply an XSLT policy after JSONToXML to re-order XML elements.
For example, suppose you have this as the output of JSONToXML.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> </soap:Header> <soap:Body> <OperationName> <ElementZ/> <ElementY/> <ElementX/> </OperationName> </soap:Body> </soap:Envelope>
And you want a different order of the child elements of OperationName. Like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> </soap:Header> <soap:Body> <OperationName> <ElementX/> <ElementY/> <ElementZ/> </OperationName> </soap:Body> </soap:Envelope>
To do that, you can apply this XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="OperationName"> <xsl:copy> <xsl:apply-templates select="ElementX" /> <xsl:apply-templates select="ElementY" /> <xsl:apply-templates select="ElementZ" /> </xsl:copy> </xsl:template> </xsl:stylesheet>
This approach will work regardless of the inbound ordering of the elements. If they are in the correct order, the XSLT will still work.
This DOES require that you hand-construct an XSLT for each schema in which the ordering of elements is important. I don't have a way to automatically generate the XSLT for every schema in which ordering is required. You might be able to build a generator that works that way, without too much trouble.
But I have to wonder whether "Fixing" the problem this way is a good thing. If the ordering really is significant, why not just tell clients to use the proper ordering in the JSON hash? Or, if the ordering really isn't significant, then change the WSDL (Schema) to relax that requirement, as described here.
The backend Soap service requires nodes in certain order. If xml payload doesn't have them in order, it fails.
The xml payload is really big with arrays and objects.
Is there a easier way to do it?
The way I see it, you have two options:
1) Have the backend send the fields in the correct order.
2) Try JAXB. I believe JAXB will allow you to map the JSON to directly to SOAP even if the order is not preserved.
I am not a java developer so don't know how to use JAXB. we are trying to see if we can fix the issue in Apigee so we don't have to ask every proxy user to be careful about this. the sequence is specified in wsdl but not sure if that would help in anyway.
There's a general XSLT way to do it, see here.
The general XSLT needs access to the schema. I am unsure if you can configure the XSLT policy in Apigee Edge to access a schema file as a variable. You may have to play with it to see if you can get it to behave in the way you want. If that does not work, then you can run the XSL Transform within a Java callout, which for sure can access a schema file, for example a schema that you embed in the JAR as a resource.
Thanks Dino. I had the same question that how can i have the xsd from wsdl to a variable in Apigee. I guess I can try adding a resource file as xsd and see if I can use it. I am not a java developer so can't use java call out. is there a way to do the same in node/javascript?
Answer by srinandans@google · Jun 02, 2017 at 09:02 PM
You can use a JavaScript on the response flow to reorder the JSON before it is converted to XML. Or, you can use a XSLT (here is a sample on how that is done: https://stackoverflow.com/questions/8305258/rearrange-xml-nodes-including-sub-nodes-by-xslt)
Using XSL transform with outputVariable from json to xml policies 1 Answer
Week5 JSON to XML Error 1 Answer
Using variables to craft XML request from JSON using AssignMessage payload 1 Answer
JSON to XML Conversion - issue with attributes and Namespaces 1 Answer
JSONtoXML policy suggesting "_" as default for InvalidCharsReplacement? 1 Answer