Jennifer
Jennifer

Reputation: 13

More efficient way of looping in JavaScript to display XML data?

Can you please look at my JavaScript and let me know if there's a more efficient way to write it in terms of looping through my XML?

My JavaScript code looks like this:

<script type="text/javascript">
function loadXMLDoc(dname)
{
    xhttp=new XMLHttpRequest();
    xhttp.open("GET",dname,false);
    xhttp.send();
    return xhttp.responseXML;
} 

var xmlDoc=loadXMLDoc("building.txt");

x=xmlDoc.getElementsByTagName('Building');

for (i=0;i<x.length;i++)
{
    txt=xmlDoc.getElementsByTagName('Building')[i].getAttribute('Name');

    document.write(txt + "<BR>");    

    y=x[i].getElementsByTagName('Tenant');

    for (j=0;j<y.length;j++)
    {
        txt1=x[i].getElementsByTagName('Tenant')[j].getAttribute('DISPLAYNAME');
        document.write("> " + txt1 + "<BR>");
    }

    document.write("<HR>");
} 

My XML data looks like this - I pasted it in PasteBin... http://pastebin.com/nhMHjCjP

Upvotes: 0

Views: 927

Answers (5)

Curley5959
Curley5959

Reputation: 119

Have a look at my answer I posted to my own question.

https://stackoverflow.com/a/17057095/2439211

I successfully created a for loop with an if else statement inside that will search the xml and display the result in a table. If no result is found, then a message saying no contact found is displayed.

Upvotes: 0

Zango
Zango

Reputation: 2387

Optimized version, using cacheing:

function loadXMLDoc(dname)
{
    xhttp=new XMLHttpRequest();
    xhttp.open("GET",dname,false);
    xhttp.send();
    return xhttp.responseXML;
} 
var xmlDoc=loadXMLDoc("building.txt");
var buildingTags = xmlDoc.getElementsByTagName('Building');
for (i=0,l=buildingTags.length;i<l;i++){
    txt=buildingTags[i].getAttribute('Name');
    document.write(txt + "<BR>");    
    var y=buildingTags[i].getElementsByTagName('Tenant');
    for (j=0,l1=y.length,j<l1;j++){
        txt1=y[j].getAttribute('DISPLAYNAME');
        document.write(" > " + txt1 + "<BR>");
    }
    document.write("<HR>");
} 

Upvotes: 1

ndp
ndp

Reputation: 21996

The slowest function in here is probably the xmlDoc.getElementsByTagName calls. Make just one call to xmlDoc.getElementsByTagName for each tag you are looking, instead of the two. You can then use it in your for loop and to access the element. Therefore: Use x the second time you mention xmlDoc.getElementsByTagName('Building') and use y the second time you mention x[i].getElementsByTagName('Tenant'). That will give you the biggest speedup.

Another change will simplify your code and allow you to optimize more easily (but maybe not too much speedup in itself): Instead of building DOM elements for document as you go, create a data structure to hold the data. This will also make debugging easier. Later, it will help you isolate performance problems-- right now, even with a profiler it would be hard to tell whether the parsing of them XML document is slow or the building up of the new DOM nodes.

Therefore:

  var buildings = []; // add this
  for(...)
    txt=x[i].getAttribute('Name');
    // SKIP: document.write(txt + "<BR>");    

    y=x[i].getElementsByTagName('Tenant');
    var tenants = []; 
    for (j=0;j<y.length;j++)
    {
        txt1=y[j].getAttribute('DISPLAYNAME');
        tenants.push(txt1); // instead of: document.write("> " + txt1 + "<BR>");
    }
    buildings.push({ name: txt, tenants: tenants }); 

Now you have cleaner "import" code. And you have a nice data structure with which to generate DOM nodes.

Upvotes: 0

vol7ron
vol7ron

Reputation: 42149

  1. Reverse Loops wouldn't work here because the order would be different (if that's important to you), but you can improve loop performance by caching the variable:

    for (i=0; i<x.length; i++)  ->   for (var i=0,n=x.length; i<n; i++)
    for (j=0; j<y.length; j++)  ->   for (var j=0,m=y.length; j<m; j++)
    
  2. instead of calling multiple independent document.writes, it's faster to build the string and just call one.

  3. it's better to not call it at all if this is an HTML page, document.write is somewhat archaic, it's better to use an element's .innerHTML or attach it another way.

Upvotes: 0

jebberwocky
jebberwocky

Reputation: 1089

change for to while

var i = length; while(i--){...};

i believe that while is much faster than for loop in javascript

Upvotes: 0

Related Questions