XML Parsing

ctsmith
Mega Sage

Let's say I have an XML document:

 <item>
        <name>% Disk Read Time _Totala</name>
        <objid>5289</objid>
</item>
<item>
        <name>% Disk Read Time _Totalb</name>
        <objid>5289</objid>
</item>
<item>
        <name>% Disk Read Time _Totalc</name>
        <objid>5289</objid>
</item>
<item>
        <name>% Disk Read Time _Totald</name>
        <objid>5289</objid>
</item>
 
I want to parse through this XML document and write a new record in a table field called payload for the values within the item element:
 
Record 1 payload
<name>% Disk Read Time _Totala</name>
        <objid>5289</objid>
 
Record 2 payload
  <name>% Disk Read Time _Totalb</name>
        <objid>5289</objid>
Record 3 payload
<name>% Disk Read Time _Totalc</name>
        <objid>5289</objid>
 
Record 4 payload
    <name>% Disk Read Time _Totald</name>
        <objid>5289</objid>
 
Any ideas on how to do this?
 
This works to a certain extent, but it breaks up every element and value into separate entries.  I just want all the elements and values within n number of item elements into separate records.
 
var xmlDoc = new XMLDocument2();
xmlDoc.parseXML(responseBody);
var node = xmlDoc.getNode('//item');
var iter = node.getChildNodeIterator();
while (iter.hasNext()) {
var n = iter.next();
gs.info('Node name: ' + n.getNodeName());
gs.info('Node value: ' + n.getNodeValue());
}
 
Thanks!
1 ACCEPTED SOLUTION

DScroggins
Kilo Sage

Hi,

 

Is that the entire XML that you are getting back in your responseBody as it seems incomplete. If that is the actual response then you will need to wrap it with an XML tag like so:

<xml>
 <item>
        <name>% Disk Read Time _Totala</name>
        <objid>5289</objid>
</item>
<item>
        <name>% Disk Read Time _Totalb</name>
        <objid>5289</objid>
</item>
<item>
        <name>% Disk Read Time _Totalc</name>
        <objid>5289</objid>
</item>
<item>
        <name>% Disk Read Time _Totald</name>
        <objid>5289</objid>
</item>
</xml>

 

This can be done by setting the responseBody to something like:

var xmlTemp = '<xml>' + responseBody + '</xml>';

 

Then you can use xmlHelper() like so:

var obj = new XMLHelper(xmlTemp).toObject();

 

This will output an object which you can iterate through and get each item as desired:

{
	"item": [
		{
			"name": "% Disk Read Time _Totala",
			"objid": "5289"
		},
		{
			"name": "% Disk Read Time _Totalb",
			"objid": "5289"
		},
		{
			"name": "% Disk Read Time _Totalc",
			"objid": "5289"
		},
		{
			"name": "% Disk Read Time _Totald",
			"objid": "5289"
		}
	]
}

Here is how you can iterate over the new object to get each individual item name and objid values:

var obj = new XMLHelper(user_data).toObject();
var itmArr = obj.item;
for(var i = 0; i < itmArr.length ; i++) {
 
  //Do something with itmArr[i].name
  //Do something with itmArr[i].objid
  
  gs.print(itmArr[i].name);
  gs.print(itmArr[i].objid);
  
}

 

Hope this helps.

 

--David

 

View solution in original post

9 REPLIES 9

Christopher, just a thought, XMLHelper is an out of the box script include that is indeed has the Accessible from set to "this application scope only".  I haven't tested it but my suggestion would be to either change that to None and be mindful of it during upgrades or clone this script using your application scope.  If it works awesome.

If the script does indeed work in scoped applications, I would strongly urge you to create an Idea in the Community Idea Portal to get this out of the box script include available to scoped applications.

Ha, yep, forgot you can switch it to accept all scopes.  Thanks!

Hi Chris,

 

We have set the OOB Script Include to be accessible from all application scopes as this is a very helpful script that we use constantly. I would recommend you do the same if possible. Then you can access the XML using helper script like so:

var obj = new global.XMLHelper(xmlString).toObject();

Also when converting an XML element that contains an attribute like:

<two att="xxx">abcd1234</two>

The resulting object will have the name set to the XML element tag name and then contain any attributes prefaced by the @ symbol. The #text will be the value of the XML element tag. For the example above the output would look like so:

 {"two": [
      {
        "@att": "xxx",
        "#text": "abcd1234"
      }
  ]
 }

Ha, yep, forgot you can switch it to accept all scopes.  Thanks!