469,268 Members | 920 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,268 developers. It's quick & easy.

Loading an XML file from local computer into a web page

Claus Mygind
571 512MB
Not sure if I am in the right forum for this question.

I am developing a server-less web page that will load an XML file so I can reformat the data and put it back on the computer.

I use FireFox 8.0.

I have no problem reading the file into the web page with "new FileReader();"

I tried both of these formats:
Expand|Select|Wrap|Line Numbers
  1.  
  2. reader.readAsBinaryString(in Blob blob);
  3. reader.readAsText(in Blob blob, [optional] in DOMString encoding);
  4.  
and both seem to load the data just fine. Although I have not figured out how to to use DOMString encoding option nor do I know if I need it.

It appears to me that I have the data in a string format even though it is a well formatted XML data.

I have not been able to convert the string into an XML object nor have I been able to read the XML nodes as if it was an xml document.

I could parse the data with indexOf(), but I would really rather try to read the data from the document nodes.

My question is this. Is there an easy way to convert the data I have read into the page, into embedded xml data?

Attached are both my app and a sample file with data to be read.
Attached Files
File Type: zip myFileReader.zip (475.0 KB, 177 views)
Nov 9 '11 #1

✓ answered by Dormilich

yea, the problem is that FileReader returns a string (reader.result) and not a Document instance. thus, before calling any XML functionality (note: .innerHTML is not part of the DOM) either use DOMParser or Document’s loadXML() method to do that conversion.

the cookbook example uses the internal parser of XMLHttpRequest (which it is doing in the background) to directly get the XMLDOM.

10 4155
Dormilich
8,651 Expert Mod 8TB
Although I have not figured out how to to use DOMString encoding option nor do I know if I need it.
if you encoded it in UTF-8 you don’t need it (default encoding), otherwise
Expand|Select|Wrap|Line Numbers
  1. // XML/document encoded in Latin-1
  2. reader.readAsText(blob, "ISO-8859-1");
Nov 9 '11 #2
Claus Mygind
571 512MB
Ok so that is not going to help me get a xml doc. What else can I do to present the data in an xml format to the web page's javaScript?
Nov 9 '11 #3
Dormilich
8,651 Expert Mod 8TB
didn’t look into myFileReader.zip, but does it have an output method (compareable to PHP’s file_get_contents() or something simple like .toString())?
Nov 9 '11 #4
Claus Mygind
571 512MB
Here's the link to Mozilla online documentation

https://developer.mozilla.org/en/DOM/FileReader

In answer to your question the output is obtained from
reader.result which can be obtained after the "onload" eventhandler fires.

Here are excerpts from my implementation of the code
Expand|Select|Wrap|Line Numbers
  1. var reader = new FileReader();
  2.  
  3.     reader.onload = function () {  
  4.         g.f1 = reader.result;
  5.         g.fileList.innerHTML = g.f1; 
  6.         var waypoints = XML2JS(reader.result, "gpx");
  7.     }
  8.  
  9.     function docStartUp(obj)
  10.     {
  11.         g.fileList = document.getElementById("fileList");
  12.         //assignEventListeners();
  13.  
  14.             var fileSelect = document.getElementById("fileSelect"),  
  15.               fileElem = document.getElementById("fileElem");  
  16.  
  17.             fileSelect.addEventListener("click", function (e) {  
  18.               if (fileElem) 
  19.               {  
  20.                 fileElem.click();  
  21.               }  
  22.               e.preventDefault(); // prevent navigation to "#"  
  23.             }, false);      
  24.  
  25.             fileElem.addEventListener("change", function (e) {
  26.                  handleFiles(this.files);
  27.             }, false);      
  28.  
  29.     }
  30.     function handleFiles(files) {
  31.  
  32.  
  33.       if (!files.length) {
  34.         g.fileList.innerHTML = "<p>No files selected!</p>";
  35.       } else {
  36.         var list = document.createElement("ul");
  37.         for (var i = 0; i < files.length; i++) {
  38.           var li = document.createElement("li");
  39.           list.appendChild(li);
  40.           var info = document.createElement("span");
  41.           info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
  42.           li.appendChild(info);
  43.         }
  44.         g.fileList.appendChild(list);
  45.  
  46.  
  47.         reader.readAsText( files[0] );
  48.         //reader.readAsBinaryString(files[0]);
  49.       }
  50.     }
  51.  
  52.  <body onload="docStartUp(this)">
  53.   <form method="post" action="">
  54.  
  55.     <input type="file" id="fileElem" multiple="true" accept="xml/*" style="display:none">  
  56.     <a href="#" id="fileSelect">Select some files</a> 
  57.  
  58.     <div id="fileList" name="fL" style="display: none;">
  59.     </div>
  60.  </form> 
  61.  </body>
  62.  
  63.  
I can understand your reluctance to opening a zip file, but the only two items in there are the html page and a .gpx (xml) file of waypoints for geocaching.

Perhaps the online documentation will more clearly explain what I am not seeing how to extract the data as an xml document.

Thanks for your help
Nov 9 '11 #5
Claus Mygind
571 512MB
Here is what the file structure looks like that I am trying to extract.

I want to parse the data between the tags
<wpt ...> and </wpt>
I have bolded it in the code below

The sample file I posted in the zip file contains about 121 of these tags. A normal file I would process would contain between 500 to 1000 waypoints.

I am trying to extract a limited amount of information and create a new .gpx file (see sample output at bottom)

Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <gpx xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" creator="Groundspeak Pocket Query" xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0 http://www.groundspeak.com/cache/1/0/cache.xsd" xmlns="http://www.topografix.com/GPX/1/0">
  3.   <name>busse woods</name>
  4.   <desc>Geocache file generated by Groundspeak</desc>
  5.   <author>Groundspeak</author>
  6.   <email>contact@groundspeak.com</email>
  7.   <time>2011-10-30T16:04:44.2275627Z</time>
  8.   <keywords>cache, geocache, groundspeak</keywords>
  9.   <bounds minlat="41.897883" minlon="-88.1792" maxlat="42.124867" maxlon="-87.871917" />
  10.   <wpt lat="42.0118" lon="-88.0251">
  11.     <time>2007-04-19T07:00:00Z</time>
  12.     <name>GC1298V</name>
  13.     <desc>Chicago Geo C-A-C-H-E: Game Clue #4 by fitzgeo, Traditional Cache (1/3)</desc>
  14.     <url>http://www.geocaching.com/seek/cache_details.aspx?guid=52e5c6c4-162e-44d9-af11-3dab8b671f46</url>
  15.     <urlname>Chicago Geo C-A-C-H-E: Game Clue #4</urlname>
  16.     <sym>Geocache</sym>
  17.     <type>Geocache|Traditional Cache</type>
  18.     <groundspeak:cache id="580906" available="True" archived="False" xmlns:groundspeak="http://www.groundspeak.com/cache/1/0">
  19.       <groundspeak:name>Chicago Geo C-A-C-H-E: Game Clue #4</groundspeak:name>
  20.       <groundspeak:placed_by>fitzgeo</groundspeak:placed_by>
  21.       <groundspeak:owner id="306610">fitzgeo</groundspeak:owner>
  22.       <groundspeak:type>Traditional Cache</groundspeak:type>
  23.       <groundspeak:container>Micro</groundspeak:container>
  24.       <groundspeak:difficulty>1</groundspeak:difficulty>
  25.       <groundspeak:terrain>3</groundspeak:terrain>
  26.       <groundspeak:country>United States</groundspeak:country>
  27.       <groundspeak:state>Illinois</groundspeak:state>
  28.       <groundspeak:short_description html="True">This cache is a camo'd test tube size pre-form container.
  29. Approximately a 1 mile round trip walk from forest preserve
  30. parking. &lt;br&gt;
  31. Like other caches in the series, it's the hike, not the hide.</groundspeak:short_description>
  32.       <groundspeak:long_description html="True">This cache is one of 25 Geo C-A-C-H-E Bingo card piece caches
  33. located in the Chicago area.&lt;br&gt;
  34. &lt;br&gt;
  35.  To get your card or to read the game details, see &lt;a rel=
  36. "nofollow" href=
  37. "http://www.geocaching.com/seek/cache_details.aspx?guid=3276bb82-3c0f-49c2-8ec8-45d63177c9c7"&gt;
  38. Chicago Geo C-A-C-H-E: Get a Card (South)&lt;/a&gt; &lt;br&gt;
  39. &lt;p&gt;&lt;b&gt;&lt;font color="blue" size="3"&gt;The C-A-C-H-E Card Word for this
  40. cache is listed on both the cache log and screw-top
  41. bottom&lt;/font&gt;&lt;br&gt;&lt;/b&gt;&lt;/p&gt;
  42. &lt;ol&gt;
  43. &lt;li&gt;Mark this Card Word on your Geo C-A-C-H-E Game Card&lt;/li&gt;
  44. &lt;li&gt;If you log this cache before obtaining a Game Card, I will
  45. assign you a Game Card number, post the number as a note, and email
  46. you a game card.&lt;/li&gt;
  47. &lt;li&gt;When you have 5 squares marked in a row (either horizontal,
  48. vertically, or diagonally) or a blackout, place a note on the
  49. &lt;a rel="nofollow" href=
  50. "http://www.geocaching.com/seek/cache_details.aspx?guid=3276bb82-3c0f-49c2-8ec8-45d63177c9c7"&gt;
  51. Chicago Geo C-A-C-H-E: Get a Card (South)&lt;/a&gt; cache.&lt;/li&gt;&lt;/ol&gt;</groundspeak:long_description>
  52.       <groundspeak:encoded_hints>Yes, you will have to walk over the hill.</groundspeak:encoded_hints>
  53.       <groundspeak:logs>
  54.         <groundspeak:log id="194447471">
  55.           <groundspeak:date>2011-10-22T19:00:00Z</groundspeak:date>
  56.           <groundspeak:type>Found it</groundspeak:type>
  57.           <groundspeak:finder id="260733">k'wren</groundspeak:finder>
  58.           <groundspeak:text encoded="False">you really get an amazing view from up here.....found a bit of fall color on the way down.
  59.  
  60. thanks for the hide [^]</groundspeak:text>
  61.         </groundspeak:log>
  62.         <groundspeak:log id="192256083">
  63.           <groundspeak:date>2011-10-12T19:00:00Z</groundspeak:date>
  64.           <groundspeak:type>Found it</groundspeak:type>
  65.           <groundspeak:finder id="1751076">Stephalana</groundspeak:finder>
  66.           <groundspeak:text encoded="False">What a climb! Couldn't I have chosen this on the way there?</groundspeak:text>
  67.         </groundspeak:log>
  68.         <groundspeak:log id="186053285">
  69.           <groundspeak:date>2011-09-11T19:57:47Z</groundspeak:date>
  70.           <groundspeak:type>Found it</groundspeak:type>
  71.           <groundspeak:finder id="2668825">3pear</groundspeak:finder>
  72.           <groundspeak:text encoded="False">Pretty views, spoiled only by the traffic noise.  TFTC</groundspeak:text>
  73.         </groundspeak:log>
  74.         <groundspeak:log id="187636177">
  75.           <groundspeak:date>2011-09-11T19:00:00Z</groundspeak:date>
  76.           <groundspeak:type>Found it</groundspeak:type>
  77.           <groundspeak:finder id="3345437">Makeithappen</groundspeak:finder>
  78.           <groundspeak:text encoded="False">cool</groundspeak:text>
  79.         </groundspeak:log>
  80.         <groundspeak:log id="186434825">
  81.           <groundspeak:date>2011-09-11T19:00:00Z</groundspeak:date>
  82.           <groundspeak:type>Found it</groundspeak:type>
  83.           <groundspeak:finder id="1971376">rikjaxon</groundspeak:finder>
  84.           <groundspeak:text encoded="False">Found on a quick hike by a great hill for canyon hiking practice.  The view from the cache brought a smile and a smiley.  TFTH.</groundspeak:text>
  85.         </groundspeak:log>
  86.       </groundspeak:logs>
  87.       <groundspeak:travelbugs />
  88.     </groundspeak:cache>
  89.   </wpt>
  90. </gpx>
  91.  

Sample output. I extract and recombine certain elements of the xml data into a new file.
Expand|Select|Wrap|Line Numbers
  1. <?xml version="1.0" encoding="UTF-8" standalone="no" ?> 
  2. <gpx xmlns="http://www.topografix.com/GPX/1/1" creator="Claus" version="1.1"> 
  3.   <wpt lat="42.0118" lon="-88.0251">
  4.  <name>GC1298V 1/3 M</name>
  5.  <cmt>1/3 M H,580906 Chicago Geo C-A-C-H-E: Game Clue #4</cmt>
  6.  <desc>Chicago Geo C-A-C-H-E: Game Clue #4</desc>
  7.  <sym>Geocache</sym>
  8.  </wpt>
  9. </gpx>
Nov 9 '11 #6
Claus Mygind
571 512MB
Well one thing I can do rather quickly is just use the .split() method, that at least gives me an array to work with where I can just discard element[0] doing it like this

Expand|Select|Wrap|Line Numbers
  1. g.wpts = reader.result.split("<wpt ");
  2.  
I then have an output like this which will be easy to cycle through
Expand|Select|Wrap|Line Numbers
  1. "lat="42.0118" lon="-88.0251"> <time>2007-04-19T07:00:00Z</time> <name>GC1298V</name> ........</wpt> "
  2.  
The only bad thing is I didn't learn to work with xml data.
Nov 9 '11 #7
Dormilich
8,651 Expert Mod 8TB
The only bad thing is I didn't learn to work with xml data.
you used it all the time when you used the DOM.

I think what you need when you have the XML string is the DOMParser.
Nov 9 '11 #8
Claus Mygind
571 512MB
Hmm! Well that is good to know. You may be right about the DOMparser as I am mixing new and old technology.

I was using a routine from JavaScript & DHTML Cookbook by Danny Goodman from O'Reilly to try to parse the xml document by navigating the nodes. But it gave me this error : "xmlDoc.getElementsByTagName is not a function file: myFileReader.html Line 122"

The line of code is as follows
Expand|Select|Wrap|Line Numbers
  1. var rawData = xmlDoc.getElementsByTagName(containerTag)[0]; 
I have bolded the line of code in the code below. It appears to me when I get to this line of code it is not seeing the read information as xml data because it is not recognizing the nodes in the data. I have confirmed that the two parameters used in the routine "xmlDoc, containerTag" both contain the appropriate information. xmlDoc does have all the information in the file selected and the containerTag is "gpx".

Danny Goodman shows how to load the xml data from the same domain (see his example for loading the data at the bottom of this post. I just found the FileReader more flexiable for serverless html page where I could select a file from anywhere on my computer. In Mr. Goodman's example I had to keep the data (gpx) file in the same folder as the html page.

As a final note, in the meantime, I took a different route and simply used the ".split("<wpt ") method to parse the incoming data into an array. Then using a for/next loop, I loop through the array and extract what I need with the "indexOf()" method. Each array element with the exception of the first one is a waypoint. Now I am in the process of creating an xml output file.

Thanks for your help, I did not learn what I wanted to learn, maybe next time.

Here is the entire html page with the embedded javaScript
Expand|Select|Wrap|Line Numbers
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3.  <head>
  4.     <script type="text/javascript">
  5.     <!--
  6.     //global object for global variables
  7.     var g = new Object();
  8.  
  9.     /*
  10.     --------------------------------------
  11.     var reader = new FileReader();
  12.     this creates an object 
  13.     which will contain the list of files 
  14.     selected by the user
  15.     --------------------------------------
  16.     */
  17.     var reader = new FileReader();
  18.  
  19.     /*
  20.     --------------------------------------
  21.     this function is run when the reader
  22.     has finished reading/loading the data
  23.     from the local file. 
  24.  
  25.     it is referenced in "handleFiles(files)"
  26.     when "reader.readAsText( files[0] );"
  27.     is executed
  28.     --------------------------------------
  29.     */
  30.     reader.onload = function () {  
  31.         g.f1 = reader.result;
  32.         g.fileList.innerHTML = g.f1; 
  33.         var waypoints = XML2JS(reader.result, "gpx");
  34.     }
  35.  
  36.  
  37.     function docStartUp(obj)
  38.     {
  39.         g.fileList = document.getElementById("fileList");
  40.         //assignEventListeners();
  41.  
  42.         /*
  43.         ------------------------------------------------------
  44.         fileSelect is the visible anchor on the form
  45.         fileElem is the hidden control <input type="file"../>
  46.  
  47.         each has an eventListener assigned
  48.         fileSelect is actived with onclick/click event by 
  49.           the user
  50.         fileElem is actived with the onchange/change event
  51.           created by the file selection by the user.
  52.         ------------------------------------------------------
  53.         */
  54.             var fileSelect = document.getElementById("fileSelect"),  
  55.               fileElem = document.getElementById("fileElem");  
  56.  
  57.             fileSelect.addEventListener("click", function (e) {  
  58.               if (fileElem) 
  59.               {  
  60.                 fileElem.click();  
  61.               }  
  62.               e.preventDefault(); // prevent navigation to "#"  
  63.             }, false);      
  64.  
  65.             fileElem.addEventListener("change", function (e) {
  66.                  handleFiles(this.files);
  67.             }, false);      
  68.  
  69.     }
  70.  
  71.     /*
  72.     -----------------------------------
  73.     handleFiles is activated by the 
  74.     filesElem eventListener. it cycles
  75.     through the list of files selectd
  76.     -----------------------------------
  77.     */
  78.     function handleFiles(files) {
  79.  
  80.         /*
  81.         ----------------------------------------------------------
  82.         this section is just stuff that cycles through the list
  83.         and displays the list on the screen
  84.         ----------------------------------------------------------
  85.         */
  86.       if (!files.length) {
  87.         g.fileList.innerHTML = "<p>No files selected!</p>";
  88.       } else {
  89.         var list = document.createElement("ul");
  90.         for (var i = 0; i < files.length; i++) {
  91.           var li = document.createElement("li");
  92.           list.appendChild(li);
  93.           var info = document.createElement("span");
  94.           info.innerHTML = files[i].name + ": " + files[i].size + " bytes";
  95.           li.appendChild(info);
  96.         }
  97.         g.fileList.appendChild(list);
  98.         /*
  99.         ------------------------------------------------------------------
  100.         this is the heart of the action
  101.         the "reader" can read the file
  102.         in several formats.
  103.         reader.abort();
  104.         reader.readAsArrayBuffer(in Blob blob); Requires Gecko 7.0
  105.         reader.readAsBinaryString(in Blob blob);
  106.         reader.readAsDataURL(in Blob file);
  107.         reader.readAsText(in Blob blob, [optional] in DOMString encoding);
  108.  
  109.         research these links for more info.
  110.         https://developer.mozilla.org/en/Using_files_from_web_applications
  111.         https://developer.mozilla.org/en/DOM/FileReader
  112.         ------------------------------------------------------------------
  113.         */         
  114.         //reader.readAsText( files[0] );
  115.         reader.readAsBinaryString(files[0]);
  116.       }
  117.     }
  118. ////////////////////////////////////////////////////////////////
  119.     var xDoc;
  120.     function XML2JS(xmlDoc, containerTag) {
  121.         var output = new Array();
  122.         var rawData = xmlDoc.getElementsByTagName(containerTag)[0];
  123.         var i, j, oneRecord, oneObject;
  124.         for (i = 0; i < rawData.childNodes.length; i++) {
  125.             if (rawData.childNodes[i].nodeType == 1) {
  126.                 oneRecord = rawData.childNodes[i];
  127.                 oneObject = output[output.length] = new Object();
  128.                 for (j = 0; j < oneRecord.childNodes.length; j++) {
  129.                     if (oneRecord.childNodes[j].nodeType == 1) {
  130.                         oneObject[oneRecord.childNodes[j].tagName] = 
  131.                             oneRecord.childNodes[j].firstChild.nodeValue;    
  132.                     }
  133.                 }
  134.             }
  135.         }
  136.         return output;
  137.     }
  138. /////////////////////////////////////////////////////////////////////
  139.     //-->
  140.     </script> 
  141.  </head>
  142.  
  143.  <body onload="docStartUp(this)">
  144.   <form method="post" action="">
  145.  
  146.     <input type="file" id="fileElem" multiple="true" accept="xml/*" style="display:none">  
  147.     <a href="#" id="fileSelect">Select some files</a> 
  148.  
  149.     <div id="fileList" name="fL" style="display: none;">
  150.     </div>
  151.  </form> 
  152.  </body>
  153. </html>
  154.  

Cookbook example for loading xml data instead of using FileReader.
Expand|Select|Wrap|Line Numbers
  1. var xDoc;
  2. // verify that browser supports XML features and load external .xml file
  3. function verifySupport(xFile) {
  4.     if (document.implementation && document.implementation.createDocument) {
  5.         // this is the W3C DOM way, supported so far only in NN6+
  6.         xDoc = document.implementation.createDocument("", "theXdoc", null);
  7.     } else if (typeof ActiveXObject != "undefined") {
  8.         // make sure real object is supported (sorry, IE5/Mac)
  9.         if (document.getElementById("msxml").async) {
  10.             xDoc = new ActiveXObject("Msxml.DOMDocument");
  11.         }
  12.     }
  13.     if (xDoc && typeof xDoc.load != "undefined") {
  14.         // load external file (from same domain)
  15.         xDoc.load(xFile);
  16.         return true;
  17.     } else {
  18.         var reply = confirm("This example requires a browser with XML support, " +
  19.             "such as IE5+/Windows or Netscape 6+.\n \nGo back to previous page?");
  20.         if (reply) {
  21.             history.back();
  22.         }
  23.     }
  24.     return false;
  25. }
  26.  
  27. // initialize first time -- invoked onload
  28. function init(xFile) {
  29.     // confirm browser supports needed features and load .xml file
  30.     if (verifySupport(xFile)) {
  31.         // let file loading catch up to execution thread
  32.         setTimeout("operativeFunction()", 1000);
  33.     }
  34. }
  35.  
  36.  
  37. ----------
  38.  
  39. <body onload="init('myData.xml');">
  40.  
  41. <!-- Try to load Msxml.DOMDocument ActiveX to assist support verification -->
  42. <object id="msxml" width="1" height="1" 
  43.     classid="CLSID:2933BF90-7B36-11d2-B20E-00C04F983E60" ></object>
  44.  
  45.  
  46. ----------
  47.  
  48. <xml id="myData" style="display:none">
  49. <worldcup>
  50.     <final>
  51.         <location>Uruguay</location>
  52.         <year>1930</year>
  53.         <winner>Uruguay</winner>
  54.         <winscore>4</winscore>
  55.         <loser>Argentina</loser>
  56.         <losscore>2</losscore>
  57.     </final>
  58.     <final>
  59.         <location>Italy</location>
  60.         <year>1934</year>
  61.         <winner>Italy</winner>
  62.         <winscore>2</winscore>
  63.         <loser>Czechoslovakia</loser>
  64.         <losscore>1</losscore>
  65.     </final>
  66.     
  67. </worldcup>
  68. </xml>
  69.  
  70.  
Nov 10 '11 #9
Dormilich
8,651 Expert Mod 8TB
yea, the problem is that FileReader returns a string (reader.result) and not a Document instance. thus, before calling any XML functionality (note: .innerHTML is not part of the DOM) either use DOMParser or Document’s loadXML() method to do that conversion.

the cookbook example uses the internal parser of XMLHttpRequest (which it is doing in the background) to directly get the XMLDOM.
Nov 10 '11 #10
Claus Mygind
571 512MB
Thanks. while you were formulating that answer for me, I took your previous suggestion and tested the DOMparser and it worked properly.

Now you have helped me to fully understand what is going on.
Nov 10 '11 #11

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

3 posts views Thread by GTi | last post: by
2 posts views Thread by Lou Civitella | last post: by
reply views Thread by tanyali | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.