Javascript: Not reading XML correctly.

~J~

~J~

Soldato
Joined
20 Oct 2003
Posts
7,558
Location
London
One of them days today :(

Can someone show why the following XML:

Code:
<?xml version="1.0" encoding="us-ascii" ?>
 <node text="Top" parentID="0">
  <node text="Spirits" parentID="" tag="1">
   <node text="Brandy" parentID="1" tag="B">
    <node text="Cognac / Armagnac" parentID="B" tag="10">
     <node text="Cognac" parentID="10" tag="23" />
     <node text="Armagnac" parentID="10" tag="8" />
    </node>
    <node text="Other Brandy" parentID="B" tag="19">
     <node text="Grape Brandy" parentID="19" tag="162">
      <node text="Other Grape Brandy" parentID="162" tag="125" />
     </node>
     <node text="Grape EDV" parentID="19" tag="164">
      <node text="Fine (EDV)" parentID="164" tag="92" />
      <node text="Grappa" parentID="164" tag="34" />
      <node text="Singani" parentID="164" tag="105" />
      <node text="Pisco" parentID="164" tag="102" />
      <node text="Marc / Lie" parentID="164" tag="100" />
     </node>
    </node>
   </node>
  </node>
 </node>

Doesn't render correctly please.

I'm running this code which seems to 'pop-up' all over the place for traversing XML files.

Code:
 function loadXML(xmlFile)
 {
  xmlDoc.async="false";
  xmlDoc.onreadystatechange=verify;
  xmlDoc.load(xmlFile);
 }
 function verify()
 { 
  if(xmlDoc.readyState!=4)
   return false; 
 }
function traverse(tree) {
        if(tree.hasChildNodes()) {
                document.write('<ul><li>');
                document.write('<b>'+tree.tagName+' : </b>');
                var nodes=tree.childNodes.length;
                for(var i=0; i<tree.childNodes.length; i++)
                        traverse(tree.childNodes(i));
                document.write('</li></ul>');
        }
        else
                document.write(tree.text);
}
 
 function initTraverse(file)
  {
  loadXML(file);
  var doc=xmlDoc.documentElement;
  traverse(doc);
 }

(Yes I know I'm not getting the attribute "text", I can cover that later, but it's still not rendering the correct child nodes, as if it's omitting the last one per child)

Totally stumped.
 
Associate
Joined
17 Feb 2006
Posts
898
Location
Fleet
From the guide this was taken from I notice theres a line

Code:
var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");

do you have this at the top of your script? Also, this is a Microsoft only function call so will only work in IE. What does "pop up" mean? Any errors/warnings in the debugging console?
 
Last edited:

~J~

~J~

Soldato
OP
Joined
20 Oct 2003
Posts
7,558
Location
London
Yeah got that, actually have the following:

Code:
 var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
 
 initTraverse("test.xml");

"for now" the IE thing isn't a problem as my testing is in IE, however would be interested to know of any cross-platform methods.
 

~J~

~J~

Soldato
OP
Joined
20 Oct 2003
Posts
7,558
Location
London
OK still having issues with this so going to look at it from a different angle.

Can someone recommend a good tutorial that will:

Allow me to traverse an XML document with children
Cross Platform
Ideally NOT using the Microsoft XMLDOM ActiveX component.

TIA.
 
Associate
Joined
17 Feb 2006
Posts
898
Location
Fleet
Did you check the error console for problems when running this? Also, what does "pop-up" mean? Can you post a screenshot or something so we know what the problem is.
 
Associate
Joined
17 Feb 2006
Posts
898
Location
Fleet
Had a few free mins so rewrote the parser. Seems to work ok on my system using an xml string. Your document should parse ok. Code can prob be neatened up a bit if your worried about it :)

Code:
function traverse(tree)
{
    txt = "";
    attrs = tree.attributes

    if(attrs != null)
    {
        txt = attrs.getNamedItem("text").value
        document.write('<ul><li>');
    }

    if(tree.childNodes.length > 0)
    {
        if(txt != "")
            document.write('<b>'+txt+' : </b>');

        for(var i=0; i<tree.childNodes.length; i++)
        {
           traverse(tree.childNodes[i]);
        }
        document.write('</li></ul>');
    }
    else
    {
        if(txt != "")
            document.write(txt+'</li></ul>');
    }
}
 
Associate
Joined
24 Jun 2008
Posts
1,168
Darn beaten to it but using your original traversing code:

The problem seemed to be the random use of the <ul> tags.

Code:
function traverse(tree) {
     document.write('<ul>');
        if(tree.hasChildNodes()) 
		{
            
                document.write('<b>'+ tree.getAttribute("text") +' : </b>');
                var nodes=tree.childNodes.length;
                for(var i=0; i<tree.childNodes.length; i++)
				{
                        traverse(tree.childNodes(i));
						if (tree.childNodes(i).hasChildNodes()){
							document.write('</ul>');
						}
				}
        }
        else
		{
               document.write('<li>'+ tree.getAttribute("text") + '</li>');
			   document.write('</ul>');
		}
}
 
Associate
Joined
17 Feb 2006
Posts
898
Location
Fleet
Darn beaten to it but using your original traversing code:

The problem seemed to be the random use of the <ul> tags.

Code:
function traverse(tree) {
     document.write('<ul>');
        if(tree.hasChildNodes()) 
		{
            
                document.write('<b>'+ tree.getAttribute("text") +' : </b>');
                var nodes=tree.childNodes.length;
                for(var i=0; i<tree.childNodes.length; i++)
				{
                        traverse(tree.childNodes(i));
						if (tree.childNodes(i).hasChildNodes()){
							document.write('</ul>');
						}
				}
        }
        else
		{
               document.write('<li>'+ tree.getAttribute("text") + '</li>');
			   document.write('</ul>');
		}
}

That still has problems. childNodes is an array not a function therefore () cant be used. Also, hasChildNodes is not valid for all the objects we will come across in traverse, you have to use childNodes.length.
 
Last edited:
Associate
Joined
17 Feb 2006
Posts
898
Location
Fleet
edit - ignore, I was testing passing the dom document rather than the documentElement :) I would rather use childNodes.length though unless a check is added to make sure any object passed to traverse is an element object and has the hasChildNodes method.
 
Last edited:
Back
Top Bottom