02-16-2020 07:36 PM
I am trying to write script for a callback application which will check if the caller has already left a call for a callback recently.
The xml will be something like
<CallBack>
<Filename>CB.xml</Filename>
<CB>
<DATE>07/02/2020</DATE>
<TIME>12:00</TIME>
<NUM>0400000000</NUM>
<Done>True</Done>
</CB>
<CB>
<DATE>08/02/2020</DATE>
<TIME>11:00</TIME>
<NUM>0288888888</NUM>
<Done>True</Done>
</CB>
<CB>
<DATE>09/02/2020</DATE>
<TIME>13:00</TIME>
<NUM>0388888888</NUM>
<Done>True</Done>
</CB>
<CB>
<DATE>12/02/2020</DATE>
<TIME>12:00</TIME>
<NUM>0400000000</NUM>
<Done>False</Done>
</CB>
</CallBack>
I have this set step
try {
javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document domDoc = builder.parse(doc_InputFile);
javax.xml.xpath.XPath XPath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
String XpathEval = str_XPATH;
String RESULT = XPath.evaluate("/CallBack/CB[NUM=0400000000]",domDoc);
return RESULT;
}
catch (java.lang.Exception e) {
e.printStackTrace();
}
But it only returns the first node from the xml.
U"\n\t07/02/2020\n 12:00\n\t0400000000\n\tTrue\n "
So I tried to change it to return a nodelist as below
try {
javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
org.w3c.dom.Document domDoc = builder.parse(doc_InputFile);
javax.xml.xpath.XPath XPath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
String XpathEval = str_XPATH;
NodeList nodeList = (NodeList) xPath.compile("/CallBack/CB[NUM=0400000000]").evaluate(domDoc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
String RESULT = RESULT + (nodeList.item(i).getFirstChild().getNodeValue());
}
return RESULT;
}
catch (java.lang.Exception e) {
e.printStackTrace();
}
I am getting an error on the NodeList line "Unable to parse expression; invalid identifier: NodeList.
It maybe I need to declare these but I am not sure of the syntax required
org.w3c.dom.Node;
org.w3c.dom.NodeList;
Regards,
Paul
02-16-2020 09:09 PM
Hi Paul,
Please look at the attachment with the sample script. It contains your code and it compiles in UCCX. I've made some small changes so it should work for you.
And here is the content of modified function to pull the data (all the changes in red):
{ try { javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance(); javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder(); org.w3c.dom.Document domDoc = builder.parse(doc_InputFile); javax.xml.xpath.XPath XPath = javax.xml.xpath.XPathFactory.newInstance().newXPath(); org.w3c.dom.NodeList nodeList = (org.w3c.dom.NodeList) XPath.compile("/CallBack/CB[NUM=0400000000]").evaluate(domDoc, javax.xml.xpath.XPathConstants.NODESET); int i = 0; for (i = 0; i < nodeList.getLength(); i++) { String RESULT = RESULT + (nodeList.item(i).getFirstChild().getNodeValue()); } return RESULT; } catch (java.lang.Exception e) { e.printStackTrace(); return null; } }
02-17-2020 02:24 PM
Hi Marek,
Thank you for your great help. The nodelist command is now accepted, but I get no results. I'll look into the nodeitem loop commands and fix that up.
Regards,
Paul
02-17-2020 07:12 AM
02-17-2020 02:30 PM
02-17-2020 03:44 PM
02-17-2020 07:05 PM
Hi Anthony,
Thank you for your reply. My understanding was that the java code returns only the nodes that matched the telephone number and then I would only loop through the matched nodes (in this case 2). Where as in Sean's solution I would need to loop through every node for a match and output the result? I could be interpreting that loop incorrectly?
Regards,
Paul
02-18-2020 07:26 AM
Oh, yep, you're right, I didn't even notice his larger iteration over the entire document.
How will you qualify "recently" in your check? Will the data be purged from the XML document regularly, leaving only recently completed callbacks in there? Thus, if there is a Done record for a calling number in the document, it could be considered recently?
If so, then you don't need to loop at all, you could just look for records which have both a Done = True and a NUM equal to the calling number (or callback number or whatever):
when = Get XML Document Data (xml, "//CB[Done='True' and NUM='" + calling_number + "']/DATE") If (when != null && when.trim() != "") True /* Found a completed callback for this number */ False
02-17-2020 01:05 PM
In the interest of replying with UCCX solution to the requirement ( since I don't speak java, or code very much...), I thought this was a fun challenge.
I created a subflow that would return the requested data. It creates an XML document from the data provided, parses each child node for the matching telephone number and returns the callback elements in a variable of type String for tags matching: DATE, TIME, NUM, and Done (in the cases where CallBack Done is 'False'). This will work for 'no,' 'single,' and 'multiple' instances of the telephone number requested, based upon the sample XML format.
It is probably not as efficient as the java code, but this is my [UCCX] solution to the original post:
Again, this could probably be done more efficiently, and I invite anyone to revise and post.
Hope this helps...
-Sean
02-17-2020 02:13 PM
02-17-2020 05:25 PM
02-18-2020 08:03 AM
So, I just found out that we are being limited to XPATH 1.0, since in XPATH 2.0 there exists a lower-case() function, and we can't use it. You'll get an Exception thrown if you try to use it, saying it does not exist. That's unfortunate. XPATH 3.1 is the current spec.
02-18-2020 08:18 AM
02-18-2020 08:50 AM
02-17-2020 02:42 PM
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