Parsing XML with namespaces

Money
Tera Contributor

I am setting up an integration with Workday.

I am making a soap call from a business rule, in which it returns XML in the response. This response (wd:Get_Workers_Response) contains about 1000 records which I would like to separate out by user (Worker), which will create a new record in our instance per user. When I convert the XML to an object, how do I access that node (if I am asking that correctly)? The node I am trying to access is <wd:Response_Data>. Under that, each worker is <wd:Worker>.

 

This script doesn't work for me

var s = new SOAPMessage('WorkdayIntegration', 'Get_Workers');
s.setStringParameter('Effective_Through', '2014-09-30T00:00:00');
s.setStringParameter('Effective_From', '2014-09-01T00:00:00');
s.setStringParameter('version', 'v21.0');
s.setStringParameter('Updated_From', '2014-09-01T00:00:00');
s.setStringParameter('type', 'Employee_ID');
s.setStringParameter('Updated_Through', '2014-09-30T00:00:00');
s.setStringParameter('Exclude_Inactive_Workers', 'true');
var response = s.post(true);

var xmlHelp = new XMLHelper(response);
var obj = xmlHelp.toObject();
JSUtil.logObject(obj, 'The Javascript Object');
var test3 = obj.getNodeText("//*[local-name()='wd:Worker']");
1 ACCEPTED SOLUTION

Hi Monroe,



Try something like the following. It basically branches its way down the response tree until it gets to the 'wd:Name_Detail_Data' object which contains properties for first, middle and last name etc. You may need to reformat the tabbing as the syntax highlighter has modified mine.



var obj = xmlHelp.toObject();   // get entire response as object


if(obj){


  var env_body = obj['env:Body'];   // get object in first tier


  if(env_body){


      var wd_get_workers_response = env_body['wd:Get_Workers_Response'];   // get object from first tier


      if(wd_get_workers_response){


          var wd_response_data = wd_get_workers_response['wd:Response_Data'];


    if(wd_response_data){


              var wd_worker_arr = wd_response_data['wd:Worker'];


  if(wd_worker_arr){


    for(var i=0;i<wd_worker_arr.length;i++){   // this will loop for all instances of the "wd:Worker" element. You may need to modify this to check for non-array though as the structure for a single element would be different


        var wd_worker = wd_worker_arr[i];   // get current worker element in array


  if(wd_worker){


    var worker_data = wd_worker['wd:Worker_Data'];


    if(worker_data){


        var wd_personal_data = worker_data['wd:Personal_Data'];


  if(wd_personal_data){


    var wd_name_data = wd_personal_data['wd:Name_Data'];


    if(wd_name_data){


        var wd_legal_name_data = wd_name_data['wd:Legal_Name_Data'];


  if(wd_legal_name_data){


    var wd_name_detail_data = wd_legal_name_data['wd:Name_Detail_Data'];


    if(wd_name_detail_data){


        // get string values from object


  var first_name = wd_name_detail_data['wd:First_Name'];


        var middle_name = wd_name_detail_data['wd:Middle_Name'];


        var last_name = wd_name_detail_data['wd:Last_Name'];


    }


  }


    }


  }


    }


  }


    }


  }


    }


      }


  }


}



Regards,


Jake


View solution in original post

12 REPLIES 12

Hi Monroe,



I'm glad to hear it worked! If you need to add some debugging, you could add some else statements to the if blocks as you go down the tree. Also, watch out for the objects that can be singular or multiple (arrays), as they need to be handled differently. My example will work when the wd:Worker object is an array etc.



Regards,


Jake


Definitely, I have actually been doing debugging using addInfoMessage and it has helped tremendously. I was unsure if the multiple if statements were the most efficient way to handle this but it seems like the only option, and it does work so I am not complaining lol. I do have ONE more question if you don't mind. When you get into an object that is an array of multiple objects which are unique by the "type" label (i.e ID has WID and Job_Profile_ID), how exactly would you pull that "type" out? Does it allow something like:


ID[i].type == 'Job_Profile_ID'   ?


Hi Monroe,



If you only want a specific case in the array (e.g the array element whose "ID" value equals a specific value, just add an IF block at the start of the FOR loop which checks for this value, if the condition is met, then copy the values to your variables/object etc. If not, the loop starts again.



// Something like this


// if "worker_arr" is the array object


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


        var current_worker = worker_arr[i];         // get current worker object


        if(current_worker){


                  if(current_worker['type']=="Job_Profile_ID"){


                            // copy values to variables as matching element has been found


                  }


                  else{


                            // else do something else as match not found in this iteration


                  }


        }


}



Regards,


Jake


I'm sorry Jake. I may have misinformed...


If I have something like


<wd:Worker>


                            <wd:Worker_Reference wd:Descriptor="Monroe Douglass (123456)">


                                  <wd:ID wd:type="WID">923jklj2334jk2mhaq13j</wd:ID>


                                  <wd:ID wd:type="Employee_ID">123456</wd:ID>


</wd:Worker_Reference>



I am attempting to pull the descriptor as well as the ID of type Employee_ID. Which led me to something like this...


//Where wd:Worker is defined as 'wd_worker'


var test = wd_worker['wd:Worker_Reference'];


  if(test){


  var test2 = test['wd:Descriptor'];


  gs.addInfoMessage("Test2 is: " + test2);


  }


I get an undefined for this statement...



I've also tried...


var test = wd_worker['wd:Worker_Reference'];


if(test){


    var currentTest = test['wd:ID'];


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


                if(currentTest['type']=="Employee_ID"){ //here I have also tried currentTest['@wd:type=="Employe_ID"']


                    gs.addInfoMessage("this works");


        }


    }


}


Money
Tera Contributor

Figured it out Jake...Here is the answer:


var test = wd_worker['wd:Worker_Reference'];


  if(test){



  var currentTest = test['wd:ID'];


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



  var objectTest = currentTest[i];


  if(objectTest['@wd:type'] == "Employee_ID"){


            var idTest = objectTest['#text'];


            gs.addInfoMessage(idTest);


        }


    }


  }



Thanks for all your help!