02-11-2021 01:44 PM
I'm looking for some suggestions on the best way to handle array's in CVP studio with a web service element. I'm building an IVR application using CVP. CVP will make a SOAP request using a Web Service Element to get a list of items a user is allowed to order.
For example the SOAP request may return something like this:
<a:ItemToOrder>
<a:Name>Item 1 Name</a:Name>
<a:package1Size>10</a:Package1Size>
<a:ProductCode>1111</a:ProductCode>
</a:ItemToOrder>
<a:ItemToOrder>
<a:Name>Item 2 Name</a:Name>
<a:package1Size>20</a:Package1Size>
<a:ProductCode>2222</a:ProductCode>
</a:ItemToOrder>
There could be 10 items available to caller one and 20 items to caller two, 30 items to caller 3, etc.
I need to save this data for later so that when a caller tries to order a item can then compare the product code with the items in the list they are allowed to order.
In the Web Service Element I can configure a number of responses manually for example:
Item[0]
Name
Size
Product Code
Item[1]
Name
Size
Product Code
...etc
However this is manual config and I wont know full count of items a caller can order until I run the SOAP request.
Does anyone have any Ideas on how to handle this more dynamically?
Thanks,
James
02-11-2021 05:27 PM
Hi - here's a very detailed answer. Lots of steps, but it should work.
1
You can parse it yourself using JavaScript in the Set Value element.
Cisco provides a package to import that contains a method named XpathUtil.eval(xml,xpath)
It takes 2 arguments, an XML string, and an XPath expression.
2
However before you can parse it, you'll need to remove all the colons from the markup tags.
That can also be done using JavaScript.
3
In the Soap WS element, select the checkbox next to Response, named Store full response
The return value will be in element data for the rest element {Data.Element.Rest_01.response_xml}
That variable name won't display in the substitution window, you'll have to key it in as response_xml.
You can log it to the Activity Log in the next element's General tab to ensure you've gotten it.
4 Now you must use JavaScript to remove the colons else it's not able to be parsed as XML.
If you haven't used the SetValue element yet, it creates a variable that's a LOCAL VARIABLE (not element or session data).
Using a SetValue element, go to its Settings tab. Right-click and select Add Variable.
Name: LocalXml
Value: {Data.Element.Rest_01.response_xml}.replace(/:/g,"")
That'll remove all the colons and save the result into the Local Variable named LocalXml
5 The variable {LocalVar.LocalXml} looks something like this. I recommend logging it to the Activity Log to be sure you've removed all the weird characters.
<aItemToOrder>
<aName>Item 1 Name</aName>
<apackage1Size>10</aPackage1Size>
<aProductCode>1111</aProductCode>
</aItemToOrder>
<aItemToOrder>
<aName>Item 2 Name</aName>
<apackage1Size>20</aPackage1Size>
<aProductCode>2222</aProductCode>
</aItemToOrder
****** I recommend you stop and test this now. View the Activity Log and be sure the LocalXml looks ok. Otherwise the next step may faile.
6 Now that you know the above worked, you can return to that Set Value element to add another variable to get the size aItemToOrder array.
In the Settings tab, right-click and select Add Variable
Name: LocalNumRows
Value: (it's all case sensitive)
importPackage(com.audium.server.cvpUtil)
var xml = {LocalVar.LocalXml}
var path = "count(//aItemToOrder)"
XpathUtil.eval(xml, path)
7
Now if you wanted to loop through all the array indices, you can use a Counter element.
8
Use a Decision element to check if ElementData Counter_01 count < LocalVariable LocalNumRows - return moreData
Otherwise: done
9
Connect the moreData path to another SetValue element to grab the data you need:
You'll be using an Xpath expression like this: //aItemToOrder[1]/aName (replacing 1 with a variable)
Create the following Local Variable:
Name: LocalItemName
Value:
importPackage(com.audium.server.cvpUtil)
var xml = {LocalVar.LocalXml}
var ctr = {Data.Element.Counter_01.count}
var path = "//aItemToOrder[" + ctr + "]/aName"
XpathUtil.eval(xml, path)
Name: LocalSize
Value:
importPackage(com.audium.server.cvpUtil)
var xml = {LocalVar.LocalXml}
var ctr = {Data.Element.Counter_01.count}
var path = "//aItemToOrder[" + ctr + "]/aPackage1Size"
XpathUtil.eval(xml, path)
10 then play this info to the caller and loop back to the counter element.
02-11-2021 05:55 PM
Thank you for the detailed response! I'll give this a try and let you know how it goes.
02-11-2021 09:32 PM
Web Services with dynamic data caused always problems to pull the response to variables. Because In the past I had to deal with this problem when the JavaSript lib was not available, WS'es can not only return arrays but also different types of objects that are optional i the WS data structure (ex. in the financial/banking integration where the customer may have multiple accounts, multiple different products).
IIn the past projects used an approach with Custom Elements which I always use it in new projects:
From the above list only point 2 is something that changes as it depends on the object definition in the WS. Other points can be standardized as Custom Standard Elements.
This approach has some advantages and disadvantages compared to JavaScript approach.
Advantages:
Disadvantages:
02-17-2021 05:51 AM
Thanks for the information. My challenge is not knowing how many products a user may order and my thought was to use a session or local variable for each order/quantity but I'm not seeing how I can create them dynamically it seems the out of box set value element I can statically create variables but not dynamically based on the callers actions.
I'm thinking your approach of custom element is they way to go here. Any chance you can point me to a template to use for a custom WebServices element?
02-17-2021 06:13 AM
To continue down the JavaScript path I'd suggest you consider using a local variable that is a JS object to hold the dynamic information. You can manipulate that object as the call progresses and put anything you want into it.
02-17-2021 07:19 AM
@jferris1979- please look at the private message.
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide