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

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

 

Thanks, David.  Yeah, that was just a sample.  Already has the XML tag and everything.  I think I'm going to take a different approach than what I was thinking, but good info!

Yep, got it.

ctsmith
Mega Sage

I've gone back to my original plan somewhat.  @davidscroggins  the XMLHelper doesn't work in a scoped app.  I should have noted that this was a scoped app I'm building.

Here's an example of what I have now and the results:

var xmlString = "<test>" +
" <one>" +
" <two att=\"xxx\">abcd1234</two>" +
" <three boo=\"yah\" att=\"yyy\">1234abcd</three>" +
" <two>another</two>" +
" </one>" +
" <number>1234</number>" +
" <one>" +
" <two att=\"xxx\">abcd1234555</two>" +
" <three boo=\"yah\" att=\"yyy\">1234abcd555</three>" +
" <two>another5555</two>" +
" </one>" +
" <number>1234</number>" +
"</test>";
var list = [];
var xmlDoc = new XMLDocument2();

xmlDoc.parseXML(xmlString);
xmlDoc.toString();
var node = xmlDoc.getNode('//one');
var iter= node.getChildNodeIterator();
while(iter.hasNext()) {
var n = iter.next();
var nodeName = n.getNodeName();
var nodeValue = n.getTextContent();
var eObj = {};
eObj[nodeName] = nodeValue;
list.push(eObj);
var newList = JSON.stringify(list);
}
gs.info(newList);
Result:
[{"#text":"    "},{"two":"abcd1234"},{"#text":"    "},{"three":"1234abcd"},{"#text":"    "},{"two":"another"},{"#text":"  "}]
I thought the whole idea of the node iterator would be to go through each node listed in the node variable and not just the first one.
 
Also, what is the #text return in the object?