-1

I have some XML that I am trying to loop over and and create a javascript a object from. Each <roleName> will be the name of the object and contain the array data of all the <users> within in.

Here is an example of the XML:

<roles>
  <role>
    <roleName>Impacted User</roleName>
    <users>
      <user>
        <reqUser>1234</reqUser>
        <userFirstName>Bob</userFirstName>
        <userLastName>Jones</userLastName>
        <userNTID>bJones</userNTID>
      </user>
      <user>
        <reqUser>5678</reqUser>
        <userFirstName>Mike</userFirstName>
        <userLastName>Neil</userLastName>
        <userNTID>mneil</userNTID>
      </user>
    </users>
  </role>
  <role>
    <roleName>Stakeholder</roleName>
    <users>
      <user>
        <reqUser>5555</reqUser>
        <userFirstName>Tim</userFirstName>
        <userLastName>F</userLastName>
        <userNTID>tf</userNTID>
      </user>
      <user>
        <reqUser>4444</reqUser>
        <userFirstName>Linda</userFirstName>
        <userLastName>E</userLastName>
        <userNTID>le</userNTID>
      </user>
    </users>
  </role>
</roles>

I am then looping over the XML and trying to create an array of objects. In this case, there would be two arrays in the object. One called Impacted Users, and the other Stakeholders:

 // Do we have users?
        var tempObj = Array(),
            temp = [];

        // Loop over the users on this request such as impacted user or stakeholder
        $(data).find('root>details>roles>role').each(function(x) {

            // Define our user data
            u = $(this);
            role = $(u).find('roleName').text();

            // Loop through the roles and create an object of data
            $(u).find('users>user').each(function(i) {

                // Define our data for the iteration
                r = $(this);

                // Create our object
                tempObj[i] = {
                    reqUser: $(r).find('reqUser').text(),
                    reqFirst: $(r).find('userFirstName').text(),
                    reqLast: $(r).find('userLastName').text(),
                    reqNTID: $(r).find('userNTID').text()
                };
            })

            // Set our array for the specific role in iteration to the object we created
            temp[role] = tempObj;


        });

        // Debug
        console.log(temp);

The issue I am running into is that the temp object is overwritten every time so only contains the data from the last iteration I believe. I tried doing something like temp[role][x] = tempObj; but it told me it was invalid. It is creating both of the objects correctly but the user data is being overwritten each time.

SBB
  • 8,560
  • 30
  • 108
  • 223
  • Just a side question, but is that XML in your hands? Meaning, are you building this XML yourself, or is it the output of an API or something, that you can't change? Because if you build it yourself, then stop using XML and go JSON. You will spare a _lot_ of pain. XML parsing is so "last decade" :) – Jeremy Thille Jun 05 '15 at 21:14
  • Sadly its an API; I can only work with what I have :/ – SBB Jun 05 '15 at 21:14
  • Just push to the array inside the loop instead. – adeneo Jun 05 '15 at 21:16
  • If you were interested in converting the xml to json in order to handle it easier in JavaScript, this might help you http://stackoverflow.com/questions/1773550/convert-xml-to-json-and-back-using-javascript – Seano666 Jun 05 '15 at 21:16
  • @adeneo I did that but they both still contain the duplicate information – SBB Jun 05 '15 at 21:20

3 Answers3

1

EDIT I rewrote your function :

data = "<roles><role><roleName>Impacted User</roleName><users><user><reqUser>1234</reqUser><userFirstName>Bob</userFirstName><userLastName>Jones</userLastName><userNTID>bJones</userNTID></user><user><reqUser>5678</reqUser><userFirstName>Mike</userFirstName><userLastName>Neil</userLastName><userNTID>mneil</userNTID></user></users></role><role><roleName>Stakeholder</roleName><users><user><reqUser>5555</reqUser><userFirstName>Tim</userFirstName><userLastName>F</userLastName><userNTID>tf</userNTID></user><user><reqUser>4444</reqUser><userFirstName>Linda</userFirstName><userLastName>E</userLastName><userNTID>le</userNTID></user></users></role></roles>"

var output = {}

// wanted output :
/*
{
 "impacted users" : [{reqUser:1234 , userfirstName : Bob}]
 "Stakeholders" : [{reqUser:5555 , userfirstName : Tim}]
}
*/
// Loop over the users on this request such as impacted user or stakeholder

$(data).find('role').each(function() {
 
 // Define our user data
 $role = $(this);
 role = $role.find('roleName').text(); // "Impacted users" or "Stakeholders"

 output[role] = [];
 
 // Loop through the roles and create an object of data
 $role.find('user').each(function() {
  // Define our data for the iteration
  $user = $(this);
  // Create our object
  output[role].push({
   reqUser: $user.find('reqUser').text(),
   reqFirst: $user.find('userFirstName').text(),
   reqLast: $user.find('userLastName').text(),
   reqNTID: $user.find('userNTID').text()
  });
 })

 // Set our array for the specific role in iteration to the object we created

});

// Debug
console.log(output);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
  • Right, and both objects in the array contain the same set of data which is what I am trying to fix. It creates the two objects fine but the users should be different in both the stake holder and impacted users – SBB Jun 05 '15 at 21:35
  • Okay, I rewrote it all, I believe now it works. I used real variable names, because working with "u", "i" and "r" is not really easy :) Use real variables names, they will be reduced upon minification anyway. – Jeremy Thille Jun 05 '15 at 21:45
  • Perfect, you made it look so easy :) – SBB Jun 05 '15 at 21:59
  • No worries dude :) I think the main change was `tempObj[i].push({` instead of `tempObj[i] = {` – Jeremy Thille Jun 06 '15 at 04:56
0

If your XML is a file loadle try play around somethings like this:

    var importFilename =  filename;
    var request = new XMLHttpRequest();
        request.open("GET", filename, false);
        request.send(null);
        xmlDocObj = $($.parseXML(request.responseText;));
        xmlDocObj.find("yourTagToFind").text(); 
ScaisEdge
  • 131,976
  • 10
  • 91
  • 107
0

Move your tempObj variable inside the loop, instead of making it global which get override.

// Loop over the users on this request such as impacted user or stakeholder
$(data).find('root>details>roles>role').each(function(x) {
// Define our user data

var tempObj = Array(),
u = $(this);
role = $(u).find('roleName').text();
slashsharp
  • 2,823
  • 2
  • 19
  • 26