There was the same problem. XML parsing seems to be impossible with webmasters. I used sax.js to parse the XML on a web worker. https://github.com/isaacs/sax-js
This is my main parser.
function xmlParser(strict){ this.parser = sax.parser(strict, {lowercase:true}); } xmlParser.prototype.parseFile = function(file, callback){ var _this = this; $.ajax.get({ cache: false, url: file, dataType: "xml", success: function(data){ var dom = _this.parseText(data.text); callback( dom ); }, error: function(data){ } }); } xmlParser.prototype.parseText = function(xlmText){ var dom = undefined; var activeNode = dom; this.parser.onerror = function (e) { }; this.parser.onend = function () {}; this.parser.ontext = function (t) { if(activeNode != undefined) activeNode.Text = t; }; this.parser.onopentag = function (node) { var node = new xmlNode(node.name, activeNode, node.attributes, dom); if(dom === undefined){ dom = node; activeNode = node; }else{ activeNode.Children.push(node); activeNode = node; } }; this.parser.onclosetag = function (node) { activeNode = activeNode.Parent; }; this.parser.write(xlmText).close(); return dom; }
xmlNode enables jQuery as tree processing.
function xmlFilterResult(){ this.length = 0; } xmlFilterResult.prototype.push = function(element){ this[this.length++] = element; } xmlFilterResult.prototype.attr = function(atribute){ if(this.length == 0) return ''; return this[0].Attributes[atribute]; } xmlFilterResult.prototype.text = function(atribute){ if(this.length == 0) return ''; return this[0].Text; } xmlFilterResult.prototype.children = function(search, result){ if(result == undefined) result = new xmlFilterResult(); if(search == undefined){ for(var i = 0; i < this.length; i++){ this[i].children(search, result); } }else{ this.find(search, true, result); } return result; } xmlFilterResult.prototype.find = function(search, nonrecursive, result){ if(result == undefined) result = new xmlFilterResult(); if(search.charAt(0) == '.') return this.findAttr('class', search.substring(1), nonrecursive, result); else if(search.charAt(0) == '#') return this.findAttr('id', search.substring(1), nonrecursive, result); else return this.findName(search, nonrecursive, result); } xmlFilterResult.prototype.findAttr = function(attr, value, nonrecursive, result){ if(result == undefined) result = new xmlFilterResult(); var child; for(var i = 0; i < this.length; i++){ child = this[i]; child.findAttr(attr, value, nonrecursive, result); } return result } xmlFilterResult.prototype.findName = function(name, nonrecursive, result){ if(result == undefined) result = new xmlFilterResult(); var child; for(var i = 0; i < this.length; i++){ child = this[i]; child.findName(name, nonrecursive, result); } return result } // xmlFilterResult.prototype.findID = function(id, nonrecursive){ // var child, result = new xmlFilterResult(); // for(var i = 0; i < this.length; i++){ // child = this[i]; // child.findID(id, nonrecursive, result); // } // return result // } function xmlNode(name, parent, atributes, root){ this.Name = name; this.Children = []; this.Parent = parent; this.Attributes = atributes; this.Document = root; this.Text = ''; } xmlNode.prototype.attr = function(atribute){ return this.Attributes[atribute]; } xmlNode.prototype.text = function(atribute){ return this.Text; } xmlNode.prototype.children = function(search, result){ if(result == undefined) result = new xmlFilterResult(); if(search == undefined){ for(i in this.Children) result.push(this.Children[i]); }else{ return this.find(search, true, result); } return result; } xmlNode.prototype.find = function(search, nonrecursive, result){ if(search.charAt(0) == '.') return this.findAttr('class', search.substring(1), nonrecursive, result); else if(search.charAt(0) == '#') return this.findAttr('id', search.substring(1), nonrecursive, result); else return this.findName(search, nonrecursive, result); } xmlNode.prototype.findAttr = function(attr, value, nonrecursive, result){ var child, i; if(result == undefined) result = new xmlFilterResult(); for(i in this.Children){ child = this.Children[i]; if(child.Attributes[attr] == value) result.push(child); if(!nonrecursive) child.findAttr(attr, value, nonrecursive, result); } return result } xmlNode.prototype.findName = function(name, nonrecursive, result){ var child, i; if(result == undefined) result = new xmlFilterResult(); for(i in this.Children){ child = this.Children[i]; if(child.Name == name){ result.push(child); } if(!nonrecursive) child.findName(name, nonrecursive, result); } return result }
Nothing special, but you understand what needs to be done.