Hi,
I want to replace existing xml values with custom values. The xml is a soap request payload.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v3="http://www.mynamespace"> <soapenv:Header> <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <Token> <Username>{User}</Username> <Password>{Pwd}</Password> </Token> </Security> </soapenv:Header> <soapenv:Body> <v3:AuthenticateUserRequest> <v3:Context>aaa</v3:Context> <v3:userName>xxx</v3:userName> <v3:password>zzz</v3:password> <v3:application>app_name</v3:application> </v3:AuthenticateUserRequest> </soapenv:Body> </soapenv:Envelope>
I want to replace the userName , Password , Context and application fields at runtime.
I want to use javascript or python callouts.
Thanks
Solved! Go to Solution.
Hi - can you elaborate a little more on your scenario?
When you say "replace values in an XML document", should we think of the original document as a static template? It's not something that's being sent in with the request, am I right?
In that case you can embed the XML template into an AssignMessage policy, and just use regular message template rules, in which you place variable references inside curly braces. For example, something like this:
<AssignMessage name='AM-SampleSoap'> <Set> <Payload contentType='application/xml'> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v3="http://www.mynamespace"> <soapenv:Header> <Security xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <Token> <Username>{User}</Username> <Password>{Pwd}</Password> </Token> </Security> </soapenv:Header> <soapenv:Body> <v3:AuthenticateUserRequest> <v3:Context>{aaa}</v3:Context> <v3:userName>{xxx}</v3:userName> <v3:password>{zzz}</v3:password> <v3:application>{app_name}</v3:application> </v3:AuthenticateUserRequest> </soapenv:Body> </soapenv:Envelope> </Payload> </Set> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <AssignTo createNew='false' transport='http' type='request'/> </AssignMessage>
In the above case you would need to have all of the strings within curly braces hold values as context variables in the flow within Edge.
Or, maybe your scenario is one in which an XML payload is being sent in with the request, and you want to modify that payload, transform it in some way. XML-to-XML. In that case I highly recommend using the XSLT policy within Apigee Edge for doing so. Once again you can employ context variables to insert values where appropriate, and you can remove values or elements (eg, remove the soap:Header). I won't show an example of the XSLT, because... well it's just XSLT and it wouldn't make sense unless we know exactly what the input document is, and exactly what the output document needs to be.
If you for whatever reason do not like the idea of XSLT, you could use the Edit-Xml-Node Java callout. But that works on exactly one node at a time, so if you wanted to replace 4 text values, and then delete the soap:header, that would be 5 different policy instances. It would work but it wouldn't be the most efficient way to do things, and therefore I would recommend that you avoid this option in this case. The Edit-Xml-Node callout is good for modifying ONE node in a document.
As for using JavaScript or Python - you certainly could do that. I can imagine embedding the XML string into a KVM entry, reading it into a context variable, then doing string manipulation within JavaScript in order to replace the variables that you want to replace. A more structured way of doing this would be to use handlebars from within a nodejs target. But that maybe overkill. Either of these approaches feels less clean to me, than the AssignMessage policy I described up top.