I recently had someone give me a potential issue that they were having when using ServiceNow’s SOAP Message library. They were consuming a WSDL where there were N number of the same element. The purpose of these elements in the SOAP body was to allow ServiceNow to send multiple attachments in one SOAP Request. The customer needed a way to insert any number of additional XML elements into the SOAP Message without having the XML escaped or treated as encapsulated CDATA.
I did some digging in the SOAPMessage library and found that in recent releases, ServiceNow has reworked their methods to easily allow just this sort of scenario.
Let’s work through an example on how this is done.
First, let’s take the example “StockQuote” SOAP Web Service in the ServiceNow SOAP Message application. If we look at the SOAP template for “StockQuote.GetQuoteCustom” function, we would see that there is a provision for a variable “${symbol}” that can be inserted into the request.
1 2 3 4 5 6 7 | <SOAP-ENV:Envelope> <SOAP-ENV:Body> <GetQuote xmlns="http://www.webserviceX.NET/"> <symbol xsi:type="xsd:string">${symbol}</symbol> </GetQuote> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
In real life, the GetQuote SOAP function can handle receiving multiple stock symbols by having the various stock symbols in a comma separated string inside of the ${symbol} variable (eg. “IBM,MSFT,GOOG,AAPL”).
So, our ServiceNow javascript code to call multiple symbols would look traditionally like this:
1 2 3 | var s = new SOAPMessage('StockQuote', 'StockQuoteSoap.GetQuote'); s.setParameter('symbol', 'IBM,MSFT,GOOG,AAPL'); var response = s.post(); |
For this example, however, let’s pretend that if we wanted to query multiple symbols, we would need to have a <symbol> element for each one such as in this XML example:
1 2 3 4 5 6 7 8 9 | <SOAP-ENV:Envelope> <SOAP-ENV:Body> <GetQuote xmlns="http://www.webserviceX.NET/"> <symbol>IBM</symbol> <symbol>GOOG</symbol> <symbol>AAPL</symbol> </GetQuote> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
In order to get the multiple XML elements into the SOAP message, we would set a variable inside of the GetQuote element, like this:
1 2 3 4 5 6 7 | <SOAP-ENV:Envelope> <SOAP-ENV:Body> <GetQuote xmlns="http://www.webserviceX.NET/"> ${symbols} </GetQuote> </SOAP-ENV:Body> </SOAP-ENV:Envelope> |
We would then adjust our script to make use of a newer SOAPMessage function called setXMLParameter(). In fact, according to the code, we should move away from using setParameter() and use either setXMLParameter() or setStringParameter(). The difference between these two functions is that the XML parameters are not escaped whereas String Parameters escape their contents.
So, our code would look something like the following:
1 2 3 4 5 6 7 8 9 | //Build the symbol XML var sXML = "<symbol>IBM</symbol>\n"; sXML += "<symbol>MSFT</symbol>\n"; sXML += "<symbol>GOOG</symbol>\n"; sXML += "<symbol>AAPL</symbol>\n"; var s = new SOAPMessage('StockQuote', 'StockQuoteSoap.GetQuote'); s.setXMLParameter('symbols', sXML); var response = s.post(); |
Of course there are other ways of doing this by diving into the SOAP Message Envelope object and traversing your XML tree, but this offers a quick and easy way of inserting a varying number of elements into your SOAP Message.
Actually, setParameter-method doesn’t escape the parameter. You have to use the newer setStringParameter-method if you want to have the string properly escaped for XML, e.g. ‘>’ should be escaped to ‘>’. So, in all cases where you want to insert XML element contents that you know don’t contain XML formatting, use setStringParameter-method and in the cases where you know that you want to insert XML contents, use setXMLParameter-method.
@Kai – You are correct in that the API has changed a bit since I originally wrote this article. The setParameter method is now deprecated and should no longer be used. Instead, as you mention, the correct calls would be setStringParameter and setXMLParameter. Thanks for the update on this blog post!
Hi John,
Is there anyway to do this within the SOAPMessage activity of a workflow?
@Ramya, Unfortunately, I don’t think that is possible. However, you can always use a “Run Script” activity instead. Then use the script that generates a SOAP Message object and then submit the parameters from there. That is actually how I prefer to do it as it tends to be more powerful.
Hi john,
I am trying to use setParameter(name, value) and want to use root node name with name.
My code is like this s.setParameter(“meta//name”,”pending code”);
But somhow it’s not working.As the payload my users are getting is empty for that meta tag.
Might be i am using wrong syntax …
After all R&D i came to know that to access root node i need to use “//” with name…
Please suggest me what is the right syntax for that….
@Anuj – setParameter() is not an XML parser function. You can’t use XPATH for the reference. setParameter sets values for ${} variables that you have created inside the SOAP Message record.
Hi ,
I am not able to set multiple values in SOAP message using setXMLParameter fucntion.
Does this have to be something related to wsdl , it is expecting string values?
I would to like to know the syntax for setting the envelope variable in the business rule script. I tried using setStringParameter but no luck.
Ex1:
${UniqueName}
Ex2:
${Domain}
${UniqueName}
Ex1:
urn:CompanyCode
urn:UniqueName${UniqueName}urn:UniqueName
urn:CompanyCode
Ex2:
urn:CommonCommodityCode
urn:Domain${Domain} urn:Domain
urn:UniqueName${UniqueName}urn:UniqueName
urn:CommonCommodityCode
Hello.
I have a REST message in Fuji where I call the setStringParameter() method and passing it a parameter whose value contains space, as follows:
var r = new sn_ws.RESTMessageV2(‘Get Group Info’, ‘get’);
r.setStringParameter(‘groupName’, ‘The Engineering Department’);
var response = r.execute();
…
But I get an HTTP error 500. I do not get the error if I passin a grpoup name whose value that does not contains spaces.
Thoughts on how to get around this?