Sunday, March 13, 2011

Using JQuery to read an external XML file

A student of mine asked me this question. He wanted to read an external XML file, parse it and load the data into a HTML Form control. In his case, he wanted to populate a select component (combo box). And he didn't want to use any PHP, Java or whatever. So that leaves me with JavaScript and HTML. This intrigued me for a bit. I haven't tried anything like this before.

So after a bit of research I stumbled into jQuery.ajax. I am familiar with jQuery - been using it for a bit so this should be quick. So, we prep the HTML file for our display:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Parsing Data from a File</title>

        <link rel="stylesheet" type="text/css" href="css/demo.css" />
        <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
        <script type="text/javascript" src="js/demo.js"></script>

    </head>
    <body>
        <h2>Parsing Data from a File</h2>
        <p class="compress">Data will be from an external file. It will formatted as an XML file
            (this could be easily be a html file). It will be be parsed using JQuery library.
            We could do this with raw JavaScript but why would you want to do that when
            there is a simpler solution?</p>

        <p>To learn in detail how this thing works <a href="http://api.jquery.com/jQuery.ajax#options">read this.</a></p>

        <div id="form-div">
        Our Combo box:
            <form id="form1" class="cmbox">
                <select class="combo1">
                </select>
            </form>
        </div>       
    </body>
</html> 
And here is the demo.js file that comes with that file. If you run both now you'll get an error. This is because we have to create a file called data.xml. You should also notice that in the demo.js file (refer to the comments) loads the data.xml if it successfully loads the file it should call a function called "parse" and should it fail it calls the "loadfail" function.
$(document).ready(function(){       // load jQuery 1.5
 function loadfail(){
  alert("Error: Failed to read file!");
 }
 
 function parse(document){
  $(document).find("combo").each(function(){
     var optionLabel = $(this).find('text').text();
     var optionValue = $(this).find('value').text();
     $('.combo1').append(
    ''
     );
  });
 }
 
 $.ajax({
  url: 'js/data.xml',    // name of file with our data
  dataType: 'xml',    // type of file we will be reading
  success: parse,     // name of function to call when done reading file
  error: loadfail     // name of function to call when failed to read
 });
});
Here is the data.xml file.
<formdata>
    <combo>
        <value>1</value>
        <text>Option 1</text>
    </combo>
    <combo>
        <value>2</value>
        <text>Option 2</text>
    </combo>
    <combo>
        <value>3</value>
        <text>Option 3</text>
    </combo>
    <combo>
        <value>4</value>
        <text>Option 4</text>
    </combo>
    <combo>
        <value>5</value>
        <text>Option 5</text>
    </combo>
</formdata>

Do note that this will fail with Chrome because of its security model. If you look at the console it will not allow you to load local files because of Origin null is not allowed by Access-Control-Allow-Origin. Whatever that is.

12 comments:

  1. You forgot to use the option tag when you append to the combo box.

    ReplyDelete
    Replies
    1. i still found error at this line "function parse(document){"

      Delete
    2. You mean that missing ';' on the 'var optionValue' line? Fixed.

      Delete
  2. I am getting the same error in line 5 ... SyntaxError: missing ) after argument list

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. But Ajax doesn't support external xml file of another domain.

    ReplyDelete
    Replies
    1. You can read an xml for another domain if you configure "another domain" to serve up the xml file. You can do this in 1 of 2 two ways:

      1. Configure Apache (or IIS) to serve xml; make sure the xml is in a path that Apache can read.
      2. Write a controller action that will return an xml response then called.

      Delete
  5. waht if i hvae attribute and i want to filter data from XML file i have xml file which has 20000 tags

    ReplyDelete
    Replies
    1. Its just going to take a long time to load. Besides, if the xml as 20000 tags then you have a design problem not a programming problem.

      Delete
  6. This comment has been removed by the author.

    ReplyDelete