How to get the particular XML node length?

Priya Shekar
Giga Guru

Hi All,

Below is my XML,

"<activity soapenc:arrayType="n1:ActivityType[6]"><ActivityType xsi:type="n1:ActivityType"><activityDtTm xsi:type="n1:WSTimeStampGMTType"><day xsi:type="xsd:short">2</day><hour xsi:type="xsd:short">7</hour><minute xsi:type="xsd:short">41</minute><month xsi:type="xsd:short">11</month><second xsi:type="xsd:short">0</second><year xsi:type="xsd:short">2015</year></activityDtTm><activityName xsi:type="xsd:string">Add Comment</activityName><comment xsi:type="xsd:string">testing add comment</comment><commentAccess xsi:type="xsd:string">Customer</commentAccess><fromId xsi:type="xsd:string"/><resultingState xsi:type="xsd:string">OPEN</resultingState><resultingStatus xsi:type="xsd:string">TO BE WRKD</resultingStatus><reasonCode xsi:type="xsd:string"/><sequenceNum xsi:type="xsd:short">8</sequenceNum><toId xsi:type="xsd:string"/><isActivityPerformedByCustomer xsi:type="xsd:boolean">true</isActivityPerformedByCustomer></ActivityType><ActivityType xsi:type="n1:ActivityType"><activityDtTm xsi:type="n1:WSTimeStampGMTType"><day xsi:type="xsd:short">2</day><hour xsi:type="xsd:short">7</hour><minute xsi:type="xsd:short">40</minute><month xsi:type="xsd:short">11</month><second xsi:type="xsd:short">0</second><year xsi:type="xsd:short">2015</year></activityDtTm><activityName xsi:type="xsd:string">Modify Ticket</activityName><comment xsi:type="xsd:string"/><commentAccess xsi:type="xsd:string">None</commentAccess><fromId xsi:type="xsd:string"/><resultingState xsi:type="xsd:string">OPEN</resultingState><resultingStatus xsi:type="xsd:string">TO BE WRKD</resultingStatus><reasonCode xsi:type="xsd:string"/><sequenceNum xsi:type="xsd:short">7</sequenceNum><toId xsi:type="xsd:string"/><isActivityPerformedByCustomer xsi:type="xsd:boolean">false</isActivityPerformedByCustomer></ActivityType><ActivityType xsi:type="n1:ActivityType><activityDtTm xsi:type="n1:WSTimeStampGMTType"><day xsi:type="xsd:short">2</day><hour xsi:type="xsd:short">7</hour><minute xsi:type="xsd:short">40</minute><month xsi:type="xsd:short">11</month><second xsi:type="xsd:short">0</second><year xsi:type="xsd:short">2015</year></activityDtTm>"

I am using XMLDocument2 API, I need to get the "activityName" node length/count and then display the values present in it in a field.

Does anyone know how to get the Node length\count using XMLDocument2 API??

Thanks,

Priya

1 ACCEPTED SOLUTION

Your XML is not complete, as jacebenson already mentioned, so I cannot do tests on it.



But, a way of parsing XML in javascript is by using the "match" function. So, taking as an example the following XML file from w3schools:



http://www.w3schools.com/xml/simple.xml



<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>



I want to get:



- value of first occurrence of a particular tag (name in this example)


- all values of a particular tag (name in this example)



For javascript code example I will be using node.js environment. I am not going to use any extra libraries besides the file system library fs one which is included by default in node.js. The fastest way for me to parse the XML was via javascript match function, as you will see below.



Getting the value of first occurrence of a particular tag:



var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/);


console.log(result[1]);



Saving the code into a js file and running it via node:



sergiu $ cat one_tag.js


var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/);


console.log(result[1]);


sergiu $ node one_tag.js


Belgian Waffles


sergiu $



To get all values of a particular tag I just do a global match first and then iterate through result array and apply the match function one more time:



var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/g);


for (i=0; i<result.length;i++){


  res = result[i].match(/<name>([^<]*)<\/name>/);


  console.log(res[1]);


}



Saving the code into a js file and running it via node:



sergiu $ cat all_tags.js


var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/g);


for (i=0; i<result.length;i++){


  res = result[i].match(/<name>([^<]*)<\/name>/);


  console.log(res[1]);


}


sergiu $ node all_tags.js


Belgian Waffles


Strawberry Belgian Waffles


Berry-Berry Belgian Waffles


French Toast


Homestyle Breakfast


sergiu $



You can apply same principle directly using javascript in the instance to parse the XML payload.


Hope this helps.



Regards,


Sergiu


View solution in original post

5 REPLIES 5

Jace Benson
Mega Sage

Priya, I don't know why you wouldn't just convert it to an object with XMLHelper.   Also the XML pasted above is missing some conent.   That may be why your attempts didn't work.



Below is how I'd get it.



var xmlString = '';


xmlString += '<activity soapenc:arrayType="n1:ActivityType[6]">';


xmlString += '       <ActivityType xsi:type="n1:ActivityType">';


xmlString += '               <activityDtTm xsi:type="n1:WSTimeStampGMTType">';


xmlString += '                       <day xsi:type="xsd:short">2</day>';


xmlString += '                       <hour xsi:type="xsd:short">7</hour>';


xmlString += '                       <minute xsi:type="xsd:short">41</minute>';


xmlString += '                       <month xsi:type="xsd:short">11</month>';


xmlString += '                       <second xsi:type="xsd:short">0</second>';


xmlString += '                       <year xsi:type="xsd:short">2015</year>';


xmlString += '               </activityDtTm>';


xmlString += '               <activityName xsi:type="xsd:string">Add Comment</activityName>';


xmlString += '               <comment xsi:type="xsd:string">testing add comment</comment>';


xmlString += '               <commentAccess xsi:type="xsd:string">Customer</commentAccess>';


xmlString += '               <fromId xsi:type="xsd:string" />';


xmlString += '               <resultingState xsi:type="xsd:string">OPEN</resultingState>';


xmlString += '               <resultingStatus xsi:type="xsd:string">TO BE WRKD</resultingStatus>';


xmlString += '               <reasonCode xsi:type="xsd:string" />';


xmlString += '               <sequenceNum xsi:type="xsd:short">8</sequenceNum>';


xmlString += '               <toId xsi:type="xsd:string" />';


xmlString += '               <isActivityPerformedByCustomer xsi:type="xsd:boolean">true</isActivityPerformedByCustomer>';


xmlString += '       </ActivityType>';


xmlString += '       <ActivityType xsi:type="n1:ActivityType">';


xmlString += '               <activityDtTm xsi:type="n1:WSTimeStampGMTType">';


xmlString += '                       <day xsi:type="xsd:short">2</day>';


xmlString += '                       <hour xsi:type="xsd:short">7</hour>';


xmlString += '                       <minute xsi:type="xsd:short">40</minute>';


xmlString += '                       <month xsi:type="xsd:short">11</month>';


xmlString += '                       <second xsi:type="xsd:short">0</second>';


xmlString += '                       <year xsi:type="xsd:short">2015</year>';


xmlString += '               </activityDtTm>';


xmlString += '               <activityName xsi:type="xsd:string">Modify Ticket</activityName>';


xmlString += '               <comment xsi:type="xsd:string" />';


xmlString += '               <commentAccess xsi:type="xsd:string">None</commentAccess>';


xmlString += '               <fromId xsi:type="xsd:string" />';


xmlString += '               <resultingState xsi:type="xsd:string">OPEN</resultingState>';


xmlString += '               <resultingStatus xsi:type="xsd:string">TO BE WRKD</resultingStatus>';


xmlString += '               <reasonCode xsi:type="xsd:string" />';


xmlString += '               <sequenceNum xsi:type="xsd:short">7</sequenceNum>';


xmlString += '               <toId xsi:type="xsd:string" />';


xmlString += '               <isActivityPerformedByCustomer xsi:type="xsd:boolean">false</isActivityPerformedByCustomer>';


xmlString += '       </ActivityType>';


xmlString += '       <ActivityType xsi:type="n1:ActivityType">';


xmlString += '               <activityDtTm xsi:type=" n1:WSTimeStampGMTType ">';


xmlString += '                       <day xsi:type="xsd:short">2</day>';


xmlString += '                       <hour xsi:type="xsd:short">7</hour>';


xmlString += '                       <minute xsi:type="xsd:short">40</minute>';


xmlString += '                       <month xsi:type="xsd:short">11</month>';


xmlString += '                       <second xsi:type="xsd:short">0</second>';


xmlString += '                       <year xsi:type="xsd:short">2015</year>';


xmlString += '               </activityDtTm>';


xmlString += '               <activityName xsi:type="xsd:string">Modify Ticket</activityName>';


xmlString += '               <comment xsi:type="xsd:string" />';


xmlString += '               <commentAccess xsi:type="xsd:string">None</commentAccess>';


xmlString += '               <fromId xsi:type="xsd:string" />';


xmlString += '               <resultingState xsi:type="xsd:string">OPEN</resultingState>';


xmlString += '               <resultingStatus xsi:type="xsd:string">TO BE WRKD</resultingStatus>';


xmlString += '               <reasonCode xsi:type="xsd:string" />';


xmlString += '               <sequenceNum xsi:type="xsd:short">7</sequenceNum>';


xmlString += '               <toId xsi:type="xsd:string" />';


xmlString += '               <isActivityPerformedByCustomer xsi:type="xsd:boolean">false</isActivityPerformedByCustomer>';


xmlString += '       </ActivityType>';


xmlString += '</activity>';



var helper = new XMLHelper(xmlString);


var obj = helper.toObject();



var j = new JSON();


//var e = j.encode(obj);


//gs.print(e);//for debugging you can see how it converts it to an obj.



//looping over the object


try {


      for (var x = 0; x < obj.ActivityType.length; x++) {


              //gs.print('typeof("typeof obj.ActivityType['+x+'].comment"): ' + typeof obj.ActivityType[x].comment);


              if (typeof obj.ActivityType[x].comment !== undefined) {


                      //gs.print('typeof("typeof obj.ActivityType['+x+'].comment[\'#text\']"): ' + typeof obj.ActivityType[x].comment['#text']);


                      if (typeof obj.ActivityType[x].comment['#text'] !== undefined) {


                              gs.print('obj.ActivityType[' + x + '].comment[\'#text\']: ' + obj.ActivityType[x].comment['#text']);


                      } else {


                              gs.print('obj.ActivityType[' + x + '].comment[\'#text\']: ' + 'undefined');


                      }


              } else {


                      gs.print('in else');


                      gs.print('obj.ActivityType[' + x + '].comment: ' + 'undefined');


              }


      }


} catch (e) {


      gs.print(e.toString());


}


/* OUTPUT


*** Script: obj.ActivityType[0].comment['#text']: testing add comment


*** Script: obj.ActivityType[1].comment['#text']: undefined


*** Script: obj.ActivityType[2].comment['#text']: undefined


*/


Hi Jace,



XMLHelper script include is present in Global application and it can't be accessed from scoped app scripts.


That's the reason I am using XMLDocument2 API.


If you have any solution other then XMLHelper, it will be very useful.



Thanks,


Priya


Your XML is not complete, as jacebenson already mentioned, so I cannot do tests on it.



But, a way of parsing XML in javascript is by using the "match" function. So, taking as an example the following XML file from w3schools:



http://www.w3schools.com/xml/simple.xml



<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>



I want to get:



- value of first occurrence of a particular tag (name in this example)


- all values of a particular tag (name in this example)



For javascript code example I will be using node.js environment. I am not going to use any extra libraries besides the file system library fs one which is included by default in node.js. The fastest way for me to parse the XML was via javascript match function, as you will see below.



Getting the value of first occurrence of a particular tag:



var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/);


console.log(result[1]);



Saving the code into a js file and running it via node:



sergiu $ cat one_tag.js


var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/);


console.log(result[1]);


sergiu $ node one_tag.js


Belgian Waffles


sergiu $



To get all values of a particular tag I just do a global match first and then iterate through result array and apply the match function one more time:



var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/g);


for (i=0; i<result.length;i++){


  res = result[i].match(/<name>([^<]*)<\/name>/);


  console.log(res[1]);


}



Saving the code into a js file and running it via node:



sergiu $ cat all_tags.js


var fs = require('fs');


var file = fs.readFileSync('./simple.xml', 'utf8');


result = file.match(/<name>([^<]*)<\/name>/g);


for (i=0; i<result.length;i++){


  res = result[i].match(/<name>([^<]*)<\/name>/);


  console.log(res[1]);


}


sergiu $ node all_tags.js


Belgian Waffles


Strawberry Belgian Waffles


Berry-Berry Belgian Waffles


French Toast


Homestyle Breakfast


sergiu $



You can apply same principle directly using javascript in the instance to parse the XML payload.


Hope this helps.



Regards,


Sergiu


Hi Sergiu,



The solution you mentioned worked perfectly.


Thanks a lot.



Regards,


Priya