home   articles   tags   browse code   

Parsing XML in Javascript and AJAX


 

Lets say your AJAX call to a server side script fetches some books from a database:
<?xml version="1.0" encoding="UTF-8" ?>
<request>
      <book>To Kill a Mockingbird</book>
      <book>The Hobbit</book>
      <book>War and Peace</book>
</request>

Your handleResponse function would probably look more like
function handleResponse(request)
{
    var xml = request.responseXML;
    var doc = (xml.firstChild.nextSibling)? xml.firstChild.nextSibling : xml.firstChild;
    for(var i=0; i<doc.childNodes.length; i++){
        if (doc.childNodes[i].nodeName.toLowerCase()=="book"){
            alert( doc.childNodes[i].firstChild.nodeValue );
        }
    }
}


Now, xml.firstChild should always refer to the xml document tag (<request> in our case), but if it has a nextSibling, then we can be sure its IE 6 screwing up again. IE 6 considers <?xml version="1.0" encoding="UTF-8" ?> to be the first child and the <request> to be the firstChild.nextSibling, so make sure to account for that like I did in the above code.

When you parse XML, avoid using getElementsByTagName(). It appears much easier to just do var booklist = xml.getElementsByTagName("book"); instead of iterating through the child nodes as above, however it can be error prone. Lets look at another example:
<?xml version="1.0" encoding="UTF-8" ?>
<request>
      <book>
<book>To Kill a Mockingbird</book>
<author>Harper Lee</author>
      </book>
      <book>
<book>The Hobbit</book>
<author>J.R.R. Tolkien</author>
      </book>
      <book>
<book>War and Peace</book>
<author>Leo Tolstoy</author>
      </book>
   </book>
</request>

In this case, var booklist = xml.getElementsByTagName("book"); returns a list of 6 xml tags: the 3 children of <request>, as well as the 3 nodes containing the book title text, and that probably isn't what you wanted to do.

To fetch the list of children by name use this function. It will only get one generation of children at a time. If you need to access the children's children, you can call this function again on its children.
function getChildrenByTagName(element,name)
{
    var list = new Array();
    name = name.toUpperCase();
    for(var i=0; i<element.childNodes.length; i++)
        if (element.childNodes[i].nodeName.toUpperCase()==name)
            list.push( element.childNodes[i] );
    return list;
}

usage:
var childlist = getChildrenByTagName(doc,'book');


Also, it can get tedious to write element.firstChild.nodeValue to get the innerText of each xml tag. Instead use this:
function getTextByTagName(element, name){
    name = name.toUpperCase();
    for(var i=0; i<element.childNodes.length; i++)
        if (element.childNodes[i].nodeName.toUpperCase()==name)
            return element.childNodes[i].firstChild.nodeValue;
    return '';
}

usage: var text = getTextByTagName(booklist[i], 'author');
 

 


 

 



Related Articles
 




home  |  privacy policy  |  terms of use  |  contact  


©2010, Zedwood Digital