Can we support a custom XML payload Inbound to a scripted REST API (XML with no request or entry tags)?

SueF
Kilo Contributor

Working on an integration with a client that can only POST XML over HTTP,  they can not consume web services SOAP or REST.   Before we go through the process of creating a scripted REST API, I want to know if this is even possible.  The XML inbound from the client does not have a SOAP envelope or the required <request><entry> tags for REST XML Posts.

Example XML looks something like this, with multiple hierarchical structures and without the REST <request> root tag or subsequent <entry> tag.

 

<incident [some proprietary namespace]>

        <taggroup1>

                  <field1/>

                  <field2/>

                  <field3/>

      </taggroup1>

        <taggroup2>

                  <field1>

                  <subgroup1>

                           <field1/>

                           <field2/>

                  </subgroup1>

            </taggroup2>

 <incident>

 

8 REPLIES 8

Ankur Bawiskar
Tera Patron
Tera Patron

@SueF 

Scripted REST API can accept both xml and json request body.

So once you receive the XML you can parse it using XML parser and do your required tasks

Scripted REST API example - script samples

Regards
Ankur

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

Hitoshi Ozawa
Giga Sage
Giga Sage

First of all, the xml document isn't proper and need to be fixed. I've also added a string value in "field1".

<?xml version="1.0"?><incident><taggroup1><field1>field1 string</field1><field2/><field3/></taggroup1><taggroup2><field1/><subgroup1><field1/><field2/></subgroup1></taggroup2></incident>

Wasn't sure is the requirement including sending xml document as a message so the following sample wraps the xml document in json. The script parse the xml document and returns the value of "/incident/taggroups/field1" which I've set to "field1 string".

Scripted REST Resource

(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

    var returnValue = '';
    try {
        var requestBody = request.body.dataString;
		var json = JSON.parse(requestBody);
		var xmlString = json.body;
		var xmlDoc = new XMLDocument2();
		xmlDoc.parseXML(xmlString);
		returnValue = xmlDoc.getNodeText("/incident/taggroup1/field1");
    } catch (e) {
		returnValue = 'Unable to process xml document';
    }
    return {
        "requestString": returnValue
    };

})(request, response);

Sending above xml document within json.

find_real_file.png

Output:

find_real_file.png

Hitoshi Ozawa
Giga Sage
Giga Sage

BTW, When I sent the xml document as "application/xml", ServiceNow REST API Explorer seems to wrap the xml with "request/entry/body". In this case, I'll need to unwrap "request/entry/body" to get the actual xml document as in the script below.

If the send xml document doesn't contain it,  the first xml document parse won't be necessary.

(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

    var returnValue = '';
    try {
        var xmlString = request.body.dataString;
        var xmlDoc = new XMLDocument2();
        xmlDoc.parseXML(xmlString);
        xmlString = xmlDoc.getNodeText("/request/entry/body");

        xmlDoc = new XMLDocument2();
        xmlDoc.parseXML(xmlString);
        returnValue = xmlDoc.getNodeText("/incident/taggroup1/field1");
    } catch (e) {
        returnValue = 'Unable to process xml document';
    }
    return {
        "requestString": returnValue
    };

})(request, response);

 

 

Hitoshi Ozawa
Giga Sage
Giga Sage

XML document can also be sent using GET. In this case, Query Parameter is defined and there is no "request/entry/body" elements.

find_real_file.png

Scripted REST Resource

(function process( /*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
    var returnValue = '';
    try {
		var xmlString = request.queryParams.xmldoc;

        xmlDoc = new XMLDocument2();
        xmlDoc.parseXML(xmlString);
        returnValue = xmlDoc.getNodeText("/incident/taggroup1/field1");
		//returnValue = xmlString;
    } catch (e) {
        returnValue = 'Unable to process xml document';
    }
    return {
        "requestString": returnValue
    };
})(request, response);

 

This script can be called by setting xml document to query parameter "xmldoc".

find_real_file.png

 

Output is as follows:

find_real_file.png