jQuery: parsing XML with namespaces: the definitive solution

jQuery: parsing XML with namespaces: the definitive solution

How to successfully parse an XML file containing namespaces with jQuery.

There are several approaches to parsing an XML feed containing namespaces with jQuery but they simply don't work properly when it comes to actually select an element that belongs to a given namespace. A common approach is based on selector escaping (namely \\) which, in theory, should match the local name of an element. However, according to my tests on an Atom feed taken from my GitHub account, this simply doesn't work at all. The point is that we should always rely on well-known features already present in the JavaScript's DOM implementation. Surprisingly, we'll find out that there's a DOM method called getElementsByTagNameNS().

My Atom feed features the Yahoo!'s media namespace:


<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">

Attached to this namespace is the thumbnail (local name) element whose url attribute contains the full URL to my profile's thumbnail:


<media:thumbnail height="30" width="30" url="..."/>

To properly select the aforementioned element we have only to use the getElementsByTagNameNS() method. This method accepts two parameters: the full namespace URI and the local name of the element to be matched.


$(document).ready(function() {

	var getXML = function() {
		var output = $('#output');
		var html = '';
		output.empty();
		
		$.ajax({
			type: 'GET',
			dataType: 'xml',
			data: null,
			url: 'file.xml',
			success: function(xml) {
				var $entries = $(xml).find('entry');
				$entries.each(function() {
					var $entry = $(this);
					var entry = $entry[0]; // DOM element
					var content = $entry.find('content').text();
					var thumbnail = entry.getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'thumbnail')[0].getAttribute('url');
					html += '<img src="' + thumbnail + '" />';
					html += content;
				});
				output.html(html);
			},
			error: function(xhr, status, text) {
				console.log(status + ': ' + text);
			}
		});
	
	};

	$('#action').on('click', getXML);

});

This solution works in all DOM Level 2 compliant browsers and it works reliably without worrying too much about escape sequences or other self-made solutions.