$.find and XML namespaces

Querying XML documents

It’s fine until you face though times and you have to find this:

<fancynamespace:tag color="green" size="huge">Kiwi</fancynamespace:tag>

or a normal-sized Kiwi, that’s even harder!

You think, you have a solution

Then you try $xmlDoc.find('fancynamespace\\:tag') which works fine in Firefox but not in Chrome. If you decide to ignore the namespace and query only for tag: $xmlDoc.find('tag'), that will work in Chrome but not in Firefox.

nodeFilter

nodeFilter is a tiny little jQuery plugin which helps you to write selectors for XML elements, even for those with namespaces. It was ispired by these few lines of code:

$.fn.filterNode = function(name) {
    return this.find('*').filter(function() {
       return this.nodeName === name;
    });
};

Source

which quickly showed its disadvantage. Because it only considers the nodeName (fancynamespace:tag) it will fail even with a slightly complex query: ('fancynamespace:tag[color="red"][size="huge]')

nodeFilter solves this problem by spliting up the entire query string with this tiny regexp /(?=\[)/g, comparing the nodeName with the very first result of split array, then applying the rest of the results to the target element with $.is.

I also created a little comparsion table to show, how $.find works in different browser (when it comes to namespaces), and what you actually get with nodeFilter:

Firefox

prefix:tagprefix\\:tagtagprefix:tag[color="green"]
$.find0600
$.nodeFilter6001

Chrome

prefix:tagprefix\\:tagtagprefix:tag[color="green"]
$.find0060
$.nodeFilter6001

GitHub

https://github.com/akoskm/nodeFilter