Problems allowing a user to select an XML file

Hi Everyone,
I’m trying to allow a user to select an XML file so that my javascript can parse it and create some pins for a google map. It works fine in Firefox, and by using FireBug I can see that the file is being accessed as expected. IE on the other hand tells me that “‘files.0’ is null or not an object” on line 68 of address-locator.php…

Here’s a link to the page: Address Locator (I’ve attached the files as well in a zip archive)

and a sampling of the XML file I’m loading:

<?xml version="1.0" encoding="UTF-8"?>
<barList>
	<establishment>
		<name>21-Seven Bar and Grill</name>
		<address>217 E Street,Davis, CA</address>
		<phone>530.757.1733</phone>
		<website>http://www.myspace.com/21seven_davis</website>
	</establishment>
	<establishment>
		<name>Beach Hut Deli</name>
		<address>109 E Street, Davis, CA</address>
		<phone>530.758.7873</phone>
		<website>http://www.beachhutdeli.com/</website>
	</establishment>
	<establishment>
		<name>Bistro 33 Davis</name>
		<address>226 F Street, Davis, CA</address>
		<phone>530.756.4556</phone>
		<website>www.bistro33.com</website>
	</establishment>
</barList>

I’ve spent the entire afternoon in Goo-gle-land - so any help is most appreciated! If I’ve missed anything or you have any questions please let me know.

Thanks in advance!
Dave.

The code I attached is still awaiting approval, so here it is:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
		<title>Address Locator</title>
		<style type="text/css">
			#map_canvas { 
				width:690px; 
				height:400px;
				float: left;
				clear: right;
				margin: 0px auto 10px 20px;
			}
		</style>
		<script src="http://www.google.com/jsapi"></script>
		<script type="text/javascript">
			var map = null;
			var geocoder = null;
			var establishmentList; // holds the XML list of all the establishments
			var mapPins = [];  // holds a listing of all the map pins
			
			google.load('maps', '3', {
				other_params: 'sensor=false'
			});
			google.setOnLoadCallback(gmapInit);
			
			/* gmapInit()
			 * initialize the google map
			 */
			function gmapInit() {
				var latlng = new google.maps.LatLng(42.204799,-111.619917); // 45.332245,-99.507536 center of north america
				var myOptions = {
					zoom: 4,
					center: latlng,
					mapTypeId: google.maps.MapTypeId.ROADMAP
				};
				
				map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
			}
			
			/* mapPin(pinName, pinAddress, pinPhone, pinWebsite, pinLat, pinLng, geocodeSuccess)
			 * includes all the information needed to create a pin with a pop up window
			 */
			function mapPin(pinName, pinAddress, pinPhone, pinWebsite, pinLat, pinLng, geocodeSuccess){
				this.pName = pinName;
				this.pAddress = pinAddress;
				this.pPhone = pinPhone;
				this.pWebsite = pinWebsite;
				this.pLat = pinLat;
				this.pLng = pinLng;
				this.success = geocodeSuccess;
			}
			
			/* getLocation(theName, theAddress, thePhoneNumber, theWebsite)
			 * gets the lat and lng of an address and adds a pin to the mapPins array.
			 */
			function getLocation(theName, theAddress, thePhoneNumber, theWebsite){
/* 
				geocoder = new google.maps.Geocoder();
				geocoder.geocode({'address': theAddress}, function(results, status){
					if (status == google.maps.GeocoderStatus.OK) {
						mapPins.push(new mapPin(theName, theAddress, thePhoneNumber, theWebsite, results[0].geometry.location, true));
					} else {
						mapPins.push(new mapPin(theName, theAddress, thePhoneNumber, theWebsite, 0, 0, false));
						alert("Geocode was not successful for the following reason: " + status);
					}
				});
*/
				// remove after working
				mapPins.push(new mapPin(theName, theAddress, thePhoneNumber, theWebsite, 42.204799, -111.619917, true));
				// end removing code
			}
			
			/* loadAddressFile()
			 * opens an XML file which contains descriptions (names), addresses, phone numbers, 
			 * and websites for a business and loads the pertetinent information into the global
			 * variable establishmentList.  Starts the call chain to have the data processed
			 */
			function loadAddressFile() {
				// open the file selected by the user
				var finput = document.getElementById("userAddressFile");
				var theFile = finput.files[0];
				
				if (theFile) {
					var fileReader = new FileReader();
					fileReader.onload = function(e){
						var xmlDoc;
						// parse (or load) the xml into xmlDoc.
						if (window.DOMParser){
							parser = new DOMParser();
							xmlDoc = parser.parseFromString(e.target.result,"text/xml");
						} else { // Internet Explorer
							xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
							xmlDoc.async="false";
							xmlDoc.loadXML(e.target.result);
						}
						// listing of the establishments
						establishmentList = xmlDoc.getElementsByTagName("establishment");
						processEstablishment(0, 1000);
					}
					fileReader.readAsText(theFile);
				} else {
					alert("Failed to load file");
				}
			}
				
			/* processEstablishment(index, delay)
			 * checks to see if the index parameter is less than the length of the list 
			 * of establishments and processes the establishment at that index in the list if it is.
			 * Then checks to see if the last entry was successfull -> retries if not or
			 * moves on to the next one and calls itself to handle the retry / next entry
			 */
			function processEstablishment(index, delay){
				if(index < establishmentList.length){
					// data from the XML file
					var theName = establishmentList[index].getElementsByTagName("name")[0].textContent;
					var theAddress = establishmentList[index].getElementsByTagName("address")[0].textContent;
					var thePhoneNumber = establishmentList[index].getElementsByTagName("phone")[0].textContent;
					var theWebsite = establishmentList[index].getElementsByTagName("website")[0].textContent;
					
					// get the current addresses geocoding and add the pin to the list
					getLocation(theName, theAddress, thePhoneNumber, theWebsite);
					
					// check to see if the attempt was successfull - if it was not and we are denied our data - increase the hold time and retry the previous attempt
					if(!mapPins[index].success){
						index--;
						delay += 5000;
					}
					
					// attempt (or re-attempt) the next establishment
					window.setTimeout(function() {
						processEstablishment(index+1, delay);
						document.getElementById("data").innerHTML += mapPins[mapPins.length-1].pName + "<br />";
					}, delay);
				}
			}
		</script>
		
		<!-- open the file of addresses if it exists and create a javascript array of the addresses -->
	
	</head>
	
	<body>
		<!-- This page is set up to allow the user to load an XML file which contains information about businesses and creates the data required to locate that business on a map -->
		<div id="map_canvas"></div>
		<div style="clear:left">
			<div style="float:left">
				<!-- User the file type to allow the user to select the file, then pass this information to javascript via accessing userAddressFile via document.getElementById("userAddressFile") in loadAddressFile() above -->
				<form id="addresses" action="address-locator.php" method="post" enctype="multipart/form-data">
					Select file: <input name="userAddressFile" id="userAddressFile" type="file" /> <input value="Upload" type="button" onclick="loadAddressFile()" />
				</form>
			</div>
			<div id="data" style="clear:left"></div>
		</div>
</body>
</html>

This is the line that’s causing the problem.

var theFile = finput.files[0];

It seems according to Microsoft, the file input has no files property

Have you tried using finput.value instead?

Hi Paul,
Thanks for the link to the MSDN Library - it looks like Microsoft is omitting more direct access by their browser to ‘files’ for security reasons…

It looks like I will have to look into uploading the file to the server, moving it (and possibly renaming it) and then have my user click another button to have the javascript request the file from the server…?

Seems convoluted - if you know of a way for me to have a user select a specific file for javascript to have access to, an example will be most appreciated :slight_smile:

Dave.