ServiceNow Scripted REST API and XML
If you are a ServiceNow?expert, you will find this boring, but some people might have never tried it or are unaware of the SN platform's capabilities.
Scripted REST API allows the SN platform to call with a custom endpoint. You can pass data to process or trigger an action in the platform. Let's have a look at how to do it. In this example, I am also using XML as payload as this is a bit harder than usual JSON.
First, you have to create a record in Scripted REST API
This?will define the endpoint (the URL that you will call from another system)
Then, you have to define the HTTP method. To be able to accept data in the HTTP request body, we will need to use the POST.
Now, we can define the script that processes the data.
(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
var xmlString = request.body.dataString;
var xmlValidation = GlideXMLUtil.validateXML(xmlString, false, false);
if (xmlValidation != null) {
gs.error("Invalid payload - " + xmlValidation);
var body = {message:"Invalid payload - " + xmlValidation};
response.setBody(body);
response.setStatus(400);
return;
}
else{
var body = {message:"The XML looks OK"};
response.setBody(body);
}
var xmlDoc = new XMLDocument2();
xmlDoc.parseXML(xmlString);
var rootNode = xmlDoc.getDocumentElement();
exploreXMLNode(rootNode);
})(request, response);
function exploreXMLNode(xmlNode) {
var iterator = xmlNode.getChildNodeIterator();
while (iterator.hasNext()) {
var childNode = iterator.next();
var childName = childNode.getNodeName();
var childText = childNode.getTextContent();
if (childName != "#text") {
gs.info(childName + ": " + childText);
exploreXMLNode(childNode);
} else {
return;
}
}
}
Let's go through some elements of the script:
领英推荐
The main function has two parameters: "request" and "response".?In "request",?we can find details about the HTTP Request?and mainly?the content.?And?here is the first trap when?you are?receiving XML instead of JSON: request.body.dataString.?Usually, you would go for?a?property "data", but this property is?actually?an object parsed out?from?the JSON text body.?You will receive an error when you get XML. The right solution is to use dataString.
Validating the string is a good practice. You can use GlideXMLUtil.validateXML?method. We will use the parameter "response" to set a proper response.
Then, we can parse the XML string into the XMLDocument2 object. I recommend using a minified version of the XML string in REST clients; otherwise, I received empty XML nodes after parsing.
You can?start accessing?XML nodes with the getNode method and the appropriate path.
In my example, I used a recursive algorithm to retrieve the?text content of all nodes in the document. The biggest challenge is to determine a stop condition for the recursion. You can find a very odd-looking condition in the code.??
if (childName != "#text") {...}
Unfortunately, when the node has?the?text content, when you call childIterator.hasNext(), you will?still get true, but in reality, there is no proper child node. Testing node name on #text did the job. This part does not look right, so I might be missing something here, but it?also can?be just a poor implementation of XML in ServiceNow.
and some data set for testing:
<breakfast_menu>food><name>Belgian Waffles</name><price>$5.95</price><description>Two of our famous Belgian Waffles with plenty of real maple syrup</description><calories>650</calories></food><food><name>Strawberry Belgian Waffles</name><price>$7.95</price><description>Light Belgian waffles covered with strawberries and whipped cream</description><calories>900</calories></food><food><name>Berry-Berry Belgian Waffles</name><price>$8.95</price><description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description><calories>900</calories></food><food><name>French Toast</name><price>$4.50</price><description>Thick slices made from our homemade sourdough bread</description><calories>600</calories></food><food><name>Homestyle Breakfast</name><price>$6.95</price><description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description><calories>950</calories></food></breakfast_menu>
If you have any question or you need help implement it let me know.