XML document in Javascript

Discussion in 'JavaScript' started by neopagan, Dec 14, 2009.

  1. #1
    Hi, please can somebody help me to get the data from an XML file with javascript?

    This is my XML file
    <film>
    <title>Film title</title>
    <episode_title>Episode title</episode_title>
    <episode_orig_title/>
    
    <pic>
    <pic_link>182616_2.jpg</pic_link>
    </pic>
    
    <attrib>some text</attrib>
    <desc>description</desc>
    
    <creators>
    
    <creator>
    <person_id>23725</person_id>
    <name>blabla</name>
    </creator>
    
    <creator>
    <person_id>246461</person_id>
    <name>blabla</name>
    </creator>
    
    </creators>
    </film>
    Code (markup):
    I need one result string in javascript, which will contain the data I need from XML. For example: var result="title-episode title<br/>description<br/>Creators: creatorname1, creatorname2,etc...";

    No more data I need.

    I tried this:

    <script type="text/javascript" language="javascript">
       var http_request = false; var rr=1;
       function makeRequest(url, parameters) {
          http_request = false;
          if (window.XMLHttpRequest) { // Mozilla, Safari,...
             http_request = new XMLHttpRequest();
             if (http_request.overrideMimeType) {
                http_request.overrideMimeType('text/xml');
             }
          } else if (window.ActiveXObject) { // IE
             try {
                http_request = new ActiveXObject("Msxml2.XMLHTTP");
             } catch (e) {
                try {
                   http_request = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {}
             }
          }
          if (!http_request) {
             alert('Cannot create XMLHTTP instance');
             return false;
          }
          http_request.onreadystatechange = alertContents;
          http_request.open('GET', url + parameters, true);
          http_request.send(null);
       }
    
       function alertContents() {
          if (http_request.readyState == 4) {
             if (http_request.status == 200) {
    
    				var xmldoc = http_request.responseXML;
                    
    				var root = xmldoc.getElementsByTagName('film').item(0);
    				
                                 
    				for (var iNode = 0; iNode < root.childNodes.length; iNode++) {
    					var node = root.childNodes.item(iNode);
    					for (i = 0; i < node.childNodes.length; i++) {
    						var sibl = node.childNodes.item(i);
    						var len = parseInt(sibl.childNodes.length / 2);
    						var arr = new Array(len);
    						var cnt = 0;
                           
    						for (x = 0; x < sibl.childNodes.length; x++) { 
    							var sibl2 = sibl.childNodes.item(x);
    							var sibl3;
    							if (sibl2.childNodes.length > 0) {
    								sibl3 = sibl2.childNodes.item(0);
    								arr[cnt] = sibl3.data;	
    								cnt++;
    							} 
    						}
                           
    						addrow(arr);
                            
                           
    					}
    				}
             } else {
                alert('There was a problem with the request.(Code: ' + http_request.status + ')');
             }
          }
       }
       function do_xml() {
    		makeRequest('portal.out_main.xml', '?test=2');
       }
       function addrow(arr) {
      
    		for (r = 0; r < arr.length; r++) {	
    		
                document.write (arr[r]);
                
       	} 
      
       }
       
    
       
    </script>
    
    
    
    <input type="button" name="button" value="GET XML" 
       onclick="javascript:do_xml();">
    
    Code (markup):
    but the result is all the data within CREATOR tag together. I need from CREATOR tag only the name, and i need the data from other tags like TITLE, etc..

    Please can you help me?
     
    neopagan, Dec 14, 2009 IP
  2. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #2
    ok from:
    var root = xmldoc.getElementsByTagName('film').item[0];
    
     var output = "";
     output += "title-" & root.getElementsByTagName('episode_title')[0].nodeValue + "<br/>";
     output += root.getElementsByTagName('desc')[0].nodeValue + "<br/>Creators: ";
     var creators = root.getElementsByTagName('name');
    for(i=0; i<creators.length; i++) {
     output += creators[i].nodeValue;
     if(i != (creators.length - 1)) output += ", ";  //not last one
     else output += "."  //last one, full stop.
    }
    document.write(output);
    
    Code (markup):
    That's typed straight into the browser but something like that should work.
     
    camjohnson95, Dec 14, 2009 IP
  3. neopagan

    neopagan Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Thank you for the quick response, but that solution works not for me...
    After pushing the GET button absolutely nothing happens.

    Hm, I really dont know whats wrong here.

    Now the last part of code looks like that:

    var root = xmldoc.getElementsByTagName('film').item[0];
    	var output = "";
     output += "title-" & root.getElementsByTagName('episode_title')[0].nodeValue + "<br/>";
     output += root.getElementsByTagName('desc')[0].nodeValue + "<br/>Creators: ";
     var creators = root.getElementsByTagName('name');
    for(i=0; i<creators.length; i++) {
     output += creators[i].nodeValue;
     if(i != (creators.length - 1)) output += ", ";  //not last one
     else output += "."  //last one, full stop.
    }
    document.write(output);
    
    
    Code (markup):
     
    neopagan, Dec 14, 2009 IP
  4. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #4
    I'll have a proper look...
     
    Last edited: Dec 14, 2009
    camjohnson95, Dec 14, 2009 IP
  5. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #5
    okay, my bad.. this works:
    
    <script type="text/javascript" language="javascript">
       var http_request = false; var rr=1;
       function makeRequest(url, parameters) {
          http_request = false;
          if (window.XMLHttpRequest) { // Mozilla, Safari,...
             http_request = new XMLHttpRequest();
             if (http_request.overrideMimeType) {
                http_request.overrideMimeType('text/xml');
             }
          } else if (window.ActiveXObject) { // IE
             try {
                http_request = new ActiveXObject("Msxml2.XMLHTTP");
             } catch (e) {
                try {
                   http_request = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {}
             }
          }
          if (!http_request) {
             alert('Cannot create XMLHTTP instance');
             return false;
          }
          http_request.onreadystatechange = alertContents;
          http_request.open('GET', url + parameters, true);
          http_request.send(null);
       }
    
       function alertContents() {
          if (http_request.readyState == 4) {
             if (http_request.status == 200) {
    
    				var root = http_request.responseXML.documentElement;
    				var output = "";
                    output += "title-" + root.getElementsByTagName('episode_title')[0].childNodes[0].nodeValue + "<br/>";
                    output += root.getElementsByTagName('desc')[0].childNodes[0].nodeValue + "<br/>Creators: ";
                    var creators = root.getElementsByTagName('name');
                    for(i=0; i<creators.length; i++) {
                        output += root.getElementsByTagName('name')[i].childNodes[0].nodeValue;
                        if(i != (creators.length - 1)) { output += ", "; }  //not last one
                        else { output += "."; }  //last one, full stop.
                    }
                    document.write(output);
    		 }
             else {
                alert('There was a problem with the request.(Code: ' + http_request.status + ')');
             }
          }
       }
       function do_xml() {
    		makeRequest('main.xml', '?test=2');
       }
       function addrow(arr) {
      
    		for (r = 0; r < arr.length; r++) {	
    		
                document.write (arr[r]);
                
       	} 
      
       }
       
    
       
    </script>
    
    
    
    <input type="button" name="button" value="GET XML" 
       onclick="javascript:do_xml();">
    
    Code (markup):
     
    camjohnson95, Dec 14, 2009 IP
  6. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #6
    notice i changed:
    var root = http_request.responseXML.documentElement
    and nodeValues must be accessed with childNodes[0]...
    Although, if you are going to have more then one film within the xml file then you need to modify this slightly.... let me know and I will show you.
     
    Last edited: Dec 14, 2009
    camjohnson95, Dec 14, 2009 IP
  7. neopagan

    neopagan Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #7
    thank you my good man! Now it works!!!

    Your code with the XML I wrote here works perfectly in FF and IE too.

    I needed slightly to change the XML for this:
    <port_data>
    
    <film>
    
    <title>Filmtitle</title>
    <title_orig>sometitle</title_orig>
    <episode_title/>
    <pic><pic_link>78160_2.jpg</pic_link></pic>
    <attrib>some attributes</attrib>
    <description>some description</description>
    
    <creators>
    <creator>
    <person_id>25645</person_id>
    <name>John David Coles</name>
    </creator>
    
    <creator>
    <person_id>206791</person_id>
    <name>Edward Ornelas</name>
    </creator>
    
    </creators>
    
    </film>
    
    </port_data>
    
    Code (markup):
    So I need only title, image, description .. and the creators but thats solved.
    Now the code looks like
    var output = "";
                    output += "title-" + root.getElementsByTagName('title')[0].childNodes[0].nodeValue + "<br/>";
                    output += "img-" + root.getElementsByTagName('pic_link')[0].childNodes[0].nodeValue + "<br/>";
                    output += root.getElementsByTagName('description')[0].childNodes[0].nodeValue + "<br/>Creators: ";
                    var creators = root.getElementsByTagName('name');
                    for(i=0; i<creators.length; i++) {
                        output += root.getElementsByTagName('name')[i].childNodes[0].nodeValue;
                        if(i != (creators.length - 1)) { output += ", "; }  //not last one
                        else { output += "."; }  //last one, full stop.
                    }
                    document.write(output);
    Code (markup):
    This works perfect in FF, but in IE works not. Something must be wrong in this line output += "title-" + root.getElementsByTagName('title')[0].childNodes[0].nodeValue + "<br/>"; because IE says something about object NULL...

    Can you please help me to resolve this problem?

    And the second problem is - the script works with any .xml file that I have in my localhost, but when I replace the main.xml for external xml file /h t t p/ , then it says There was a problem with the request.(Code:0)
     
    Last edited: Dec 14, 2009
    neopagan, Dec 14, 2009 IP
  8. neopagan

    neopagan Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #8
    please can someone help me with that?
     
    neopagan, Dec 19, 2009 IP
  9. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #9
    You cannot load an external file using AJAX. The file must be located on the same server as the file calling it.
     
    camjohnson95, Dec 19, 2009 IP
  10. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #10
    It seems to work fine in IE7 for me. Maybe try changing the 'var root=....' line back to:
    var root = http_request.responseXML;

    But I don't have any problems with this code an IE7.
     
    camjohnson95, Dec 19, 2009 IP
  11. neopagan

    neopagan Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #11
    Hm, very interesting... i tried this in IE6, IE7 and IE8, and in all these browsers it says 'null' is null or not an object, and IE6 says only Object required

    All shows the line output += "title-" + root.getElementsByTagName('title')[0].childNodes[0].nodeValue + "<br/>";

    I tried to change var root = http_request.responseXML; but nothing helped.

    Im going to make a try on my server, because I tested it on my localhost.

    You can try the whole code here LIVE inbazar.sk/test/skuska.php

    thanks
     
    Last edited: Dec 19, 2009
    neopagan, Dec 19, 2009 IP
  12. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #12
    camjohnson95, Dec 19, 2009 IP
  13. neopagan

    neopagan Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #13
    I changed the XML now for another shorter one, but now nothing works..

    I think its time to give it up... I really dont know how to do it...

    The problem is that XML has sometimes some tags empty, sometimes not - its online generated, I cant change it.

    But if I cant access external XML with ajax, so that solution will not help me.
     
    neopagan, Dec 19, 2009 IP
  14. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #14
    The problem is that the character's like 'ý' aren't being parsed. I'm not sure of a work around, but i'm sure there must be one.
     
    camjohnson95, Dec 19, 2009 IP
  15. ranacseruet

    ranacseruet Peon

    Messages:
    302
    Likes Received:
    3
    Best Answers:
    0
    Trophy Points:
    0
    #15
    ranacseruet, Dec 19, 2009 IP
  16. neopagan

    neopagan Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #16
    camjohnson95 - maybe its only something with coding of the XML file, thanks anyway.

    ranacseruet - thank you, I will check that article.
     
    neopagan, Dec 20, 2009 IP
  17. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #17
    Yes the XML cannot be parsed:
    
    The XML page cannot be displayed 
    Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later. 
    
    
    --------------------------------------------------------------------------------
    
    [B]An invalid character was found in text content. Error processing resource 'http://inbazar.sk/test/php.xml?test=2'. Line 3,...
    
    <title>Summertonsk
     [/B]
    
    Code (markup):
    The charset needs to needs to be changed and the file that your are requesting: http://inbazar.sk/test/php.xml?test=2 ... is incomplete at that. Go to it in your browser and 'View Source'. It ends unexpectedly at:
    '
    <link_l2>http://www.port.sk/pls/po/portal.out_main?i_area=7&amp;i_p1=316935&amp;i_city_id=3372&amp;i_county_id=-1&amp;i_xml=1&am
    
    Code (markup):
    You CAN access external XML with javascript but you need to use PHP to load the external XML.... E.g: getXML.php (located on your server), contacts the remote server and fetches the data from it, it then outputs that data. You then access your getXML.php using AJAX. It serves as a proxy. If you've given up then that is okay, but if you really want to get this working, PM me.
     
    Last edited: Dec 20, 2009
    camjohnson95, Dec 20, 2009 IP
  18. neopagan

    neopagan Peon

    Messages:
    8
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #18
    Thanks..I think I have solved it with php parsing XML and Ajax as you suggested -

    I used something like

    <script type="text/javascript">
    		function loadContent(id){
    		$("#container").load("parse.php?o="+ide+"&i="+ur+"");
    		}
    	</script>
    Code (markup):
    In that php file I parse the xml with php and send back the result as HTMl output, that is displayed in container DIV.

    So it works now.. Thanks for a good idea! Im just learning things about ajax, javascript.

    And then i think we have solved the javascript parsing local XML file too, you had right about the bad file encoding, and that was the error.

    So if I find any problem, I will ask you. Thank you again for your help and time!
     
    neopagan, Dec 20, 2009 IP