1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Javascript: Not reading XML correctly.

Discussion in 'HTML, Graphics & Programming' started by ~J~, 5 Feb 2010.

  1. ~J~

    Sgarrista

    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.
     
  2. Ladforce

    Hitman

    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: 5 Feb 2010
  3. ~J~

    Sgarrista

    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.
     
  4. ~J~

    Sgarrista

    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.
     
  5. Ladforce

    Hitman

    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.
     
  6. AJK

    Wise Guy

    Joined: 8 Sep 2009

    Posts: 1,722

    Location: UK

  7. Ladforce

    Hitman

    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>');
        }
    }
    
     
  8. SimonCHere

    Wise Guy

    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>');
    		}
    }
    
     
  9. Ladforce

    Hitman

    Joined: 17 Feb 2006

    Posts: 898

    Location: Fleet

    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: 8 Feb 2010
  10. SimonCHere

    Wise Guy

    Joined: 24 Jun 2008

    Posts: 1,168

    That is of course true, but for this XML it does work.

    () appears to work in IE. it should have been [] though.
     
  11. Ladforce

    Hitman

    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: 8 Feb 2010