[AJAX/PHP/JS] Indexjumps in XML data, c'mon in and I'll explain!

GooS

Azrael
Reaction score
154
So the title may not help much so here's the deal.

I wish to get a directory listing into javascript, using AJAX and a PHP script.
The PHP script alters the header so that the response is an XML document and it presents the data generated as XML.

Such as:

Code:
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<anchors>
  <anchor>
    <name>subdir</name>
    <type>dir</type>
    <href>root/subdir</href>
  </anchor>
  ...
</anchors>

[Generated XML document]
(The items listed are just random, popped some in there for testing purposes)

Ok, so far so fine, I created the AJAX, also worked, so lets jump to now.
The script works, if you can call it that, BUT, in my loop through the XML
data I must add 2 indexes per itteration as every other element is 'undefined'
which I find quite odd. I must also double up the max index (list size) in order
to get all elements, it solves the problem and gives me no new ones cept for
the fact that it all seems very strange. Here's the test response:

(Yes the child elements must skip one aswell, there are three for every anchor node but 0,2,4 are undefined)
(index must start at 1 not to try and fetch the first element which is undefined)

Code:
var xmlDoc = xmlhttp.responseXML;
txt = "";
for(var i = 1; i < (xmlDoc.getElementsByTagName('anchor').length*2); i += 2){
  name = xmlDoc.childNodes[0].childNodes[i].childNodes[1].childNodes[0].nodeValue + '<br />';
  type = xmlDoc.childNodes[0].childNodes[i].childNodes[3].childNodes[0].nodeValue + '<br />';
  href = xmlDoc.childNodes[0].childNodes[i].childNodes[5].childNodes[0].nodeValue + '<br />';
  txt += name + type + href + '<br /><br />';
}
document.getElementById('result').innerHTML = txt;

tldr; Odd problem, every other element in my XML object is undefined, what's up?
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
I would just use JSON, as it can be natively parsed in JavaScript (though there are more safe libraries around than the native method).

It's very easy to create JSON in PHP as well.
 

UndeadDragon

Super Moderator
Reaction score
448
Which element is undefined? The parent one or one of the child elements?
 

GooS

Azrael
Reaction score
154
Lyerae, I think I'll do that, however I'm still curious as to why I have to jump 1 element.

UndeadDragon, the elements not used in the code are undefined, the root element exists [0], but then I have to jump every other child to get defined elements, and then every two children of that element.
 

Magentix

if (OP.statement == false) postCount++;
Reaction score
107
Don't waste time trying to figure out why XML isn't working when you can use JSON instead.

Leave XML for other stuff that can't parse JSON.
 

GooS

Azrael
Reaction score
154
I have remade it into JSON and it works like a charm when implemented into the application I made it for!

But even so I am still curious as to why the XML problems occured!
 

Magentix

if (OP.statement == false) postCount++;
Reaction score
107
I have remade it into JSON and it works like a charm when implemented into the application I made it for!

But even so I am still curious as to why the XML problems occured!

XML is the dinosaur version of JSON, don't even bother figuring it out.
Just be happy the web has moved on to JSON and smile when you see other application developers still having to struggle with XML :cool:
 

Lyerae

I keep popping up on this site from time to time.
Reaction score
105
I'm curious about the problem as well...
(I'm not an expert parsing XML, but...)

Code:
for(var i = 1; i < (xmlDoc.getElementsByTagName('anchor').length*2); i += 2)

Shouldn't that be...

Code:
for(var i = 1; i < (xmlDoc.getElementsByTagName('anchor').length*2); i += 1)
?
 

JerseyFoo

1/g = g-1
Reaction score
40
Lyerae, read for detail.

This occurs because modern browsers consider white-space their own elements.

---
About your logic, there's no reason to have a "anchors" node.

Could have also avoided problems by doing it right.
PHP:
var anchors = xmlDoc.getElementsByTagName('anchor'), a;
var txt = '', endl = '<br/>';

while ( (a = anchors.shift()) ){
    txt += a.name +  endl + a.type + endl + a.href + endl + endl + endl;
}
Works with both regardless of XML, JSON, white-space or not. Is much faster, and a lot easier to read.
 

GooS

Azrael
Reaction score
154
Seems odd to consider whitespace an element, ah well, thanks for answering that one!

Really? I don't need a root in an XML structure? (Multiple anchor nodes are added below that's why I wrote ...)

That's some neat code you got there, just two whings I wonder wonder about.

Wouldn't the first assignment attempt to set anchors to a, which is yet to be defined in the code?

And guessing it's typos that you refer to a as e in the loop.
 

Magentix

if (OP.statement == false) postCount++;
Reaction score
107
By the way, irrelevant to the OP, but relevant to loops:

PHP:
for(var i = 1; i < (xmlDoc.getElementsByTagName('anchor').length*2); i += 1)
is a bad habit. If you use that type of loop on DOM collections (or even XML collections), you may get an endless loop.

It's much safer to do this instead:
PHP:
for(var i = 1,len = xmlDoc.getElementsByTagName('anchor').length*2; i < len; i ++)

Then it could be optimized to:
PHP:
for(var i = xmlDoc.getElementsByTagName('anchor').length*2; i--;)
Which is more than twice as fast, but reverts the order of your loop, so only use it when that doesn't matter.
 

JerseyFoo

1/g = g-1
Reaction score
40
Code:
var anchors = xmlDoc.getElementsByTagName('anchor'), a;
var txt = '', endl = '<br/>';
...is the same as...
Code:
var anchors = xmlDoc.getElementsByTagName('anchor');
var a;
var txt = '';
var endl = '<br/>';
Just a way of organization.

Yes that was a typo, I usually use 'e' as a local var for elements.

Really? I don't need a root in an XML structure?
Nope.

To elaborate on what Magnetix said...
PHP:
var e;
for ( var i = 0;  ( e = array.shift() ); i++ ){
    // this would also work, setting both i and e (the key and element)
    // this is because FOR actually performs a conditional on the middle statement, as it is performing a conditional on ( i-- ) above.
}

PHP:
var i = 1;
if ( i-- )
    document.write(i);  // OUTPUTS 0

i = 1;
if ( --i )
    document.write(i);  // doesn't run

It would've helped a lot if I knew these little things off the bat, maybe you'll find it useful someday.

----

To avoid the white-space problem, as you will run into this, you're actually supposed to use a new set of properties designed for Elements only. https://developer.mozilla.org/en/DOM/element.children
Code:
parent.children[]
parent.firstElementChild
parent.lastElementChild
parent.firstElementChild.nextElementSibling
Problem is, only the newest browsers support this, even though it's been a production standard for nearly 2 years now. I personally believe the entire white-space node stuff is ridiculous and they should've used entities for it, but some higher power supports this. At least now if you see someone claiming it's pointless to strip whitespace from your PHP/etc output, you know they don't have their details straight.
 

GooS

Azrael
Reaction score
154
Magentix, the first thing you said, guessing you're talking about live objects, they could be inserted into and therefor increase in length while looping making it infinite, don't see a problem there mainly because I don't append anything into that element anywhere in my code.

Yes hat loop could be optimized, which it has been, getting a property of an array of a document every itteration is pretty heavy just to get the length number.
I now use a do while with the same arguments that are in your last loop there, don't know which is faster if there are any diffrences, but I like the look of it!

Thanks for the comment!

JerseyFoo, I must read closer into the comma operator and thanks for the loop and whitespace as elements info!
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top