Link to home
Start Free TrialLog in
Avatar of alainbryden
alainbrydenFlag for Canada

asked on

Loading an XML url with javascript.

Hey. I'm trying to create a small script that, when my page is visited, the script will run as follows:

1. It will load an url containing XML text ( http://synthlight.miniville.fr/xml )
2. It will read in certain values and if the sum of unemployment + (100 - transport) + criminality + pollution is equal to 0
3. It will automatically redirect the page with " window.location = "http://synthlight.miniville.fr/"; "

4. If the sum of the above is not 0, it will pick the largest of unemployment, (100 - transport), criminality and pollution, and redirect to http://synthlight.miniville.fr/com, .../tra, .../sec or .../env respectively.

I have an ftp where I can upload and test the script, what I need are some people to help me pull the script together. Here is what I have attempted so far, but loading it does nothing, as the script is clearly flawed:

_______________________________________________
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
      <head>
            <META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
            <title>Synthlight City</title>
      </head>
      <body>
<script type="text/javascript">
   <!--
   var xmlDoc;
function importXML()
{
      if (document.implementation && document.implementation.createDocument)      {
            xmlDoc = document.implementation.createDocument("", "", null);
            xmlDoc.onload = createTable;
      }
      else if (window.ActiveXObject)      {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.onreadystatechange = function ()      {
                  if (xmlDoc.readyState == 4) createTable()
            };
       }
      else      {
            alert('Your browser can\'t handle this script');
            return;
      }
      xmlDoc.load("http://synthlight.miniville.fr/xml");
}
   importXML();
   var city = xmlDoc.getElementsByTagName("city");
   var unemployment = parseInt(city[0].getAttribute("unemployment"));
   var transport = parseInt(city[0].getAttribute("transport"));
   var criminality = parseInt(city[0].getAttribute("criminality"));
   var pollution = parseInt(city[0].getAttribute("pollution"));

   if (unemployment + (100 - transport) + criminality + pollution == 0)
      window.location = "http://synthlight.miniville.fr/";
   else if( (100 - transport) > unemployment && (100 - transport) > criminality && (100 - transport) > pollution )
      window.location = "http://synthlight.miniville.fr/tra";
   else if( unemployment > criminality && unemployment > pollution )
      window.location = "http://synthlight.miniville.fr/com";
   else if( criminality > pollution )
      window.location = "http://synthlight.miniville.fr/sec";
   else
      window.location = "http://synthlight.miniville.fr/env";
   //-->
</script>
You should be redirected to synthlight city automatically. If not, click <a href="http://synthlight.miniville.fr/">here</a>.
      </body>
</html>
_______________________________________________


One thing I know for sure is that xmlDoc.load("http://synthlight.miniville.fr/xml"); does not work because that particular function expects a .xml file, not a url as a parameter.
ASKER CERTIFIED SOLUTION
Avatar of kawas
kawas
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
doh, ignore the line
    grayOut(true);
as its there un-necessarily
and url is meant to be your url for the xml file
Avatar of alainbryden

ASKER

Thank you.

Alright, I've implemented your code instead of the other method for importing the XML file, and placed it in an HTML file which is to be run here:

http://ride.dsu.dal.ca/test2.html

as you can see, script does not run. Did I incorrectly implement it, or are there still some other bugs I need to work out?

--
Alain
sorry, my method will only work if the server hosting the script and the server hosting the xml are on the same domain.
Also consider that this script is meant to run in both Mozilla and Internet Explorer Browsers. With your use of ActiveXObjects, will this even work in firefox?
yeah it would work in both, given tthe limitation above
what if I were to have some other script copy the contents of that url to a new page on my own host. Surely the url can be opened and read by a script even if it's on another host?
that would work..

you could have an intermediate servlet/cgi script that your javascript would talk to ... that would definitely work
just make sure that your intermediate servlet/cgi script returns contentType text/xml
I tested it by copying the contents of http://synthlight.miniville.fr/xml  to a file called "somexml" and hosted it. Having done that, the following code works perfectly:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
      <head>
            <META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
            <title>Synthlight City</title>
      </head>
      <body>
<script type="text/javascript">
   <!--

function getXMLhttp() {
      var C=null;
      try{
            C=new ActiveXObject("Msxml2.XMLHTTP");
      }catch(e){
            try{
                  C=new ActiveXObject("Microsoft.XMLHTTP");
            }catch(sc){
                  C=null;
            }
      }
      if(!C&&typeof XMLHttpRequest!="undefined"){
            C=new XMLHttpRequest();
      }
      return C;
}

request = getXMLhttp();
if (request) {
      request.open("GET", "somexml", true);
      request.onreadystatechange = function() {
         if (request.readyState == 4 && request.status == 200) {
            var xmlDoc = request.responseXML;

   var city = xmlDoc.getElementsByTagName("city");
   var unemployment = parseInt(city[0].getAttribute("unemployment"));
   var transport = parseInt(city[0].getAttribute("transport"));
   var criminality = parseInt(city[0].getAttribute("criminality"));
   var pollution = parseInt(city[0].getAttribute("pollution"));

   if (unemployment + (100 - transport) + criminality + pollution == 0)
      window.location = "http://synthlight.miniville.fr/";
   else if( (100 - transport) > unemployment && (100 - transport) > criminality && (100 - transport) > pollution )
      window.location = "http://synthlight.miniville.fr/tra";
   else if( unemployment > criminality && unemployment > pollution )
      window.location = "http://synthlight.miniville.fr/com";
   else if( criminality > pollution )
      window.location = "http://synthlight.miniville.fr/sec";
   else
      window.location = "http://synthlight.miniville.fr/env";

         }
   
       };
}
request.send(null);


</script>
You should be redirected to synthlight city automatically. If not, click <a href="http://synthlight.miniville.fr/">here</a>.
      </body>
</html>



Now my only question is, how do I get around and manually updating that file? I would like the most up to date version as available on that link posted above.

--
Alain
are you using cgi? or servlets?
I am just pasting that text into an HTML document, and hosting it on ftp://ride.dsu.dal.ca/ under the name test.html . When someone visits the link, it is run. That is all I know.
hmm, if you want to do this automatically, you will have to create a cgi script that the server will host or a java servlet (again that the server will host).

otherwise, you will have to update the file manually or through a cron job ...
I don't mind putting additional scripts on here to make this work. Ideally, I could include the additional scripts on this same script, but I don't know what ether of those are and how they work. Can you show me the cgi script or java servlet that I would need?

Remember - the original is here:

 http://synthlight.miniville.fr/xml

and I suppose the script will move it to here:

 http://ride.dsu.dal.ca/xml
okay, give me < an hour
here is the perl script, it has to be placed in the cgi-bin/ folder of your server in order to work. Also, modify the url in the javascript to point to the url that houses the perl script

--------------------------------------------------

#!/usr/bin/perl

use strict;
use LWP::Simple;
use CGI qw/:standard/;

my $url = "http://synthlight.miniville.fr/xml";
my $cgi = new CGI;
my $content = get $url;
print $cgi->header('text/xml'), $content if $content;
return;
I can't even begin to pretend I know what to do with that. My host gave me a public_www/ folder and that's it. I don't know how to run that perl script, and if I put it in a folder called cgi-bin/ and reference it's url in my other script, I get nothing.

I'll tell you what, if you have a solution for me - that's great, but I'll give you the points for this question and ask another one with my different problems.
you will have to talk to the host and ask them to either allow you to run cgi scripts in your directory or to place that script in their cgi-bin directory.

CGI scripts are 'dangerous' to web servers if the author doesnt know what they are doing, etc.

Keep posting your questions until we resolve this problem.
by the way, all that script does is every time its called, it calls your url and returns the contents (the xml) back to you.
is there any other way of accessing the http://synthlight.miniville.fr/xml with HTML scripting. Even if I have to to a instr search or something, I need a script to be able to extract certain values from that page.
Error 1: You can see what I mean about the script not working on both by going here:

http://ride.dsu.dal.ca/test.html

this script has all forwarding commented out so the page actually stops and you can view the source and generated html. I have it generating the values that it read. Viewed in IE, you see a bunch of numbers from the saved XML file on my host. Viewed in Firefox, you see a lot of NAN, meaning the code is running, because the html is being generated, but it's not retrieving the values.



Error 2: This is a script that I will be giving to someone else eventually to run off their host, and it should all be embeddable within a single HTML file that can be viewed by anyone visiting that link. They won't have access to this cgi/bin folder you speak of, so we need to find some way to read the contents of http://synthlight.miniville.fr/xml without doing that script which copies all it's contents. I figure if a person can browse to this url, why can't a script browse to it, search its source for strings like <unemployment> and use it. I still don't understand why the .open method doesn't work on url's from another source, but if there's no way around that, then we'll need to do this without XMLDOM objects.


--
Alain Bryden
scripts cant read across domains for security. i am thinking about how to do this another way, but it might take a while.
The only other way that i can think of is flaky and may require you to tweak things.

use an iframe:
<iframe id='xml' src="http://synthlight.miniville.fr/xml" style="display:none;" onLoad="importXML();"> </iframe>

and in the importXML() function, do something like:
   var iframe ;
function importXML() {
      iframe = document.getElementById('xml');
      if (document.implementation && document.implementation.createDocument)
      {
            xmlDoc = document.implementation.createDocument("", "", null);
            xmlDoc.importNode(iframe.contentDocument.firstChild(), true);
      }
      else if (window.ActiveXObject)
      {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.importNode(iframe.contentDocument.firstChild(), true);
       }
      else
      {
            alert('Your browser can\'t handle this script');
            return;
      }
      
}

the reason i say its flaky, is that unless the iframe has fully loaded, this method fails. you might be able to tweak it a little bit to get it to work all the time, but I dont think you will have much success.

I would re-consider the cgi-bin way because it isnt that difficult to pull off.

Good luck.
better yet, instead of cloning the node, as is done in importXML, just do:

var doc = document.getElementById('xml').contentDocument;

and manipulate doc.
document.getElementById('xml').contentDocument; returns 'property does not exist' even though the frame exists, and document.getElementById('xml') returns a valid object.
on explorer right?

function importXML() {
      iframe = document.getElementById('xml');
      if (document.implementation && document.implementation.createDocument)
      {
            xmlDoc = document.implementation.createDocument("", "", null);
            xmlDoc.importNode(iframe.contentDocument.firstChild(), true);
      }
      else if (window.ActiveXObject)
      {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.importNode(document.frames["xml"].document.firstChild, true);
       }
      else
      {
            alert('Your browser can\'t handle this script');
            return;
      }
     
}

Hopefully that one works ... firstChild may or may not be applicable to ie. you may have to substitute it with something else.
Hmm. When running in firefox, the frame loads allright, but the function fails to run. I can't tell why because I can't debug it.

 When running in internet explorer, I get a runtime error, if I refuse to debug, the frame loads, then I get another runtime error: Line: 28 Error: Expected ')'. If I continue, the frame loads, and then I get an exception "An exception of type 'Microsoft JScript runtime errorL Object expected' was not handled. I don't know where it was thrown, because the debugger won't step through the script.

if you want to look at these errors yourself, it is posted at http://ride.dsu.dal.ca/test.html

I implemented the script as follows:

Line 28 is the else statement from what you showed above.
27      }
28      else
29      {
30            alert('Your browser can\'t handle this script');

_______________________________________________________________________
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
      <head>
            <META HTTP-EQUIV="Content-Script-Type" CONTENT="text/javascript">
            <title>Synthlight City</title>
      </head>
      <body>
You should be redirected to synthlight city automatically. If not, click <a href="http://synthlight.miniville.fr/">here</a>.
<p ID="p1"></p><p ID="p2"></p>

<script type="text/javascript">
   <!--
function importXML()
{
      iframe = document.getElementById('xml');
      if (document.implementation && document.implementation.createDocument)
      {
            xmlDoc = document.implementation.createDocument("", "", null);
            xmlDoc.importNode(iframe.contentDocument.firstChild(), true);
      }
      else if (window.ActiveXObject)
      {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.importNode(document.frames["xml"].document.firstChild, true);
      }
      else
      {
            alert('Your browser can't handle this script');
            return;
      }

      var city = xmlDoc.getElementsByTagName("city");
      var unemployment = parseInt(city[0].getElementsByTagName("unemployment")[0].textContent);
      if (isNaN(unemployment))
            unemployment = parseInt(city[0].getElementsByTagName("unemployment")[0].text);
      var transport = parseInt(city[0].getElementsByTagName("transport")[0].textContent);
      if (isNaN(transport))
            transport = parseInt(city[0].getElementsByTagName("transport")[0].text);
      var criminality = parseInt(city[0].getElementsByTagName("criminality")[0].textContent);
      if (isNaN(criminality))
            criminality = parseInt(city[0].getElementsByTagName("criminality")[0].text);
      var pollution = parseInt(city[0].getElementsByTagName("pollution")[0].textContent);
      if (isNaN(pollution))
            pollution = parseInt(city[0].getElementsByTagName("pollution")[0].text);
      document.getElementById("p1").innerHTML = ("" + unemployment + " Unemployment<br>" + transport + " Transport<br>" + criminality + " Criminality<br>" + pollution + " Pollution");
      if (unemployment + (100 - transport) + criminality + pollution == 0)
      {
            document.getElementById("p2").innerHTML = ("<br><br><br>Population needs Attention!<br>");
            window.location = "http://synthlight.miniville.fr/";
      }
      else if( (100 - transport) >= unemployment && (100 - transport) >= criminality && (100 - transport) >= pollution )
      {
            document.getElementById("p2").innerHTML = ("<br><br><br>Transport needs Attention!<br>")
            window.location = "http://synthlight.miniville.fr/tra";
      }
      else if( unemployment >= criminality && unemployment >= pollution )
      {
            document.getElementById("p2").innerHTML = ("<br><br><br>Commerce (for unemployment) needs Attention!<br>");
            window.location = "http://synthlight.miniville.fr/com";
      }
      else if( criminality >= pollution )
      {
            document.getElementById("p2").innerHTML = ("<br><br><br>Security (for crime) needs Attention!<br>");
            window.location = "http://synthlight.miniville.fr/sec";
      }
      else
      {
            document.getElementById("p2").innerHTML = ("<br><br><br>Environment (for pollution) needs Attention!<br>");
            window.location = "http://synthlight.miniville.fr/com";
      }
}

   -->
</script>
<iframe id='xml' src="http://synthlight.miniville.fr/xml" onLoad="importXML();"> </iframe>
      </body>
</html>
alert('Your browser can't handle this script');

should read
alert('Your browser can\'t handle this script');
or
alert("Your browser can't handle this script");

make sure to escape quotes.
Thanks for that.

Line 24 is now giving me an Access is Denied error
(xmlDoc.importNode(document.frames["xml"].document.firstChild, true);)
I guess that's all there is to it eh?