ServiceNow has come yet another step closer to making it easier to consume web services (or other XML based API’s) and quickly create records based off of the XML data that is returned. In the Winter 2011 release, ServiceNow quietly introduced a library that allows a script to convert an XML string into a record in any table in the system.

We’re going to go through a simple example of how you might do this. The example I am creating was written in the “Background Scripts” module of my test instance. You can do the same, or your can create a business rule or other script to test this out.

For this example, I am going to generate an XML string on the fly. Normally, you would be receiving this XML string from a SOAP web service or other API that you are consuming. To keep this simple, however, we will just generate some XML to test the new library.

1
2
3
4
5
6
7
8
9
10
11
12
13
//Set up the XML string
var xml = "<xml>";
var template = "<cmdb_ci_server><asset_tag>___ASSETTAG</asset_tag><name>___NAME</name><operational_status>1</operational_status><order_date/><os>Linux Red Hat</os><os_version>Enterprise Server 3</os_version><short_description>A Test CI for XML based Record Generation</short_description></cmdb_ci_server>";


// Generate a number of Configuration Items within the XML.
var numOfItemsToCreate = 15;
for(var i=0; i<numOfItemsToCreate; i++){
  xml += template.replace("___ASSETTAG", "JJATAG_"+i).replace("___NAME", "JJANAME_"+i);
}

//Finish up the XML string
xml += "</xml>";

What this bit of code did was create a variable called “xml”. It also creates a variable called “template”. The “template” variable stores an XML node that contains elements in the node that have the name name as elements in my table. Typically our destination table would be an Import Set Table. Once we are finished running this script, we would have an XML string that looks like the string below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<xml>
    <cmdb_ci_server>
        <asset_tag>JJAATAG_0</asset_tag>
        <can_print>false</can_print>
        <cd_rom>false</cd_rom>
        <name>JJAANAME_0</name>
        <operational_status>1</operational_status>
        <order_date/>
        <os>Linux Red Hat</os>
        <os_version>Enterprise Server 3</os_version>
        <short_description>Glide Production </short_description>
    </cmdb_ci_server>
    <cmdb_ci_server>
        <asset_tag>JJAATAG_1</asset_tag>
        <can_print>false</can_print>
        <cd_rom>false</cd_rom>
        <name>JJAANAME_1</name>
        <operational_status>1</operational_status>
        <order_date/>
        <os>Linux Red Hat</os>
        <os_version>Enterprise Server 3</os_version>
        <short_description>Glide Production </short_description>
    </cmdb_ci_server>
    <cmdb_ci_server>
        <asset_tag>JJAATAG_2</asset_tag>
        <can_print>false</can_print>
        <cd_rom>false</cd_rom>
        <name>JJAANAME_2</name>
        <operational_status>1</operational_status>
        <order_date/>
        <os>Linux Red Hat</os>
        <os_version>Enterprise Server 3</os_version>
        <short_description>Glide Production </short_description>
    </cmdb_ci_server>
    <cmdb_ci_server>
        <asset_tag>JJAATAG_3</asset_tag>
        <can_print>false</can_print>
        <cd_rom>false</cd_rom>
        <name>JJAANAME_3</name>
        <operational_status>1</operational_status>
        <order_date/>
        <os>Linux Red Hat</os>
        <os_version>Enterprise Server 3</os_version>
        <short_description>Glide Production </short_description>
    </cmdb_ci_server>
    <cmdb_ci_server>
        <asset_tag>JJAATAG_4</asset_tag>
        <can_print>false</can_print>
        <cd_rom>false</cd_rom>
        <name>JJAANAME_4</name>
        <operational_status>1</operational_status>
        <order_date/>
        <os>Linux Red Hat</os>
        <os_version>Enterprise Server 3</os_version>
        <short_description>Glide Production </short_description>
    </cmdb_ci_server>
</xml>

Since our XML string has a list of records within the XML, we need to determine just how many records are contained in the xml string. In order to do this, I am going to use the XMLDocument library (see Script Includes -> XMLDocument). We will first use XPATH on the root node to get all of the nodes under that root. In our example, the record nodes are contained in the “/xml” root node. We get the number of the records inside of “/xml” by using the following code:

1
2
3
4
//Determine how many Records are in the XML string (as if we didn't already know)
xmlDoc = new XMLDocument(xml);
var nodes = xmlDoc.getNodes("/xml/*");
var numCIs = nodes.getLength();

Now that we have the number of records that we will want to load into our table, we will need to instantiate the new “ImportSetUtil” library that was created to do this work for us.

1
2
//Load the ImportSetUtil library...this will do the record population for us
var isUtil = new ImportSetUtil();

The method that we will use inside of this new library is the “loadFromXML” method. That method takes three parameters:

  1. XPATH string that points to the root of the element node list that contains each record data item
  2. The XML Document of our incoming data
  3. The name of the ServiceNow table where the data will be generated

We will iterate through all of the number of records contained in the XML string an call the “loadFromXML” method on each xml element tree that contains one record.

1
2
3
4
//Load the XML data into a record on the table
for(var i=1; i<=numCIs; i++){
 var res = isUtil.loadFromXML("/xml/cmdb_ci_server["+i+"]/*", xmlDoc, "cmdb_ci_server");
}

After executing the entire script, our XML data is loaded into the table as seen in the screen shot below: