5

I'm using jQuery to parse some XML, like so:

function enumOptions(xml) {
   $(xml).find("animal").each(function(){  
       alert($(this).text());
   });
}

enumOptions("<root><animal>cow</animal><animal>squirrel</animal></root>");

This works great. However if I try and look for nodes called "option" then it doesn't work:

function enumOptions(xml) {
   $(xml).find("option").each(function(){  
      alert($(this).text());
   });
}

enumOptions("<root><option>cow</option><option>squirrel</option></root>");

There's no error, just nothing gets alerted, as if the find isn't finding anything. It only does it for nodes called option everything else I tested works ok!

I'm using the current version of jQuery - 1.4.2.

Anyone any idea?

TIA.

bg

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
push 22
  • 1,172
  • 3
  • 15
  • 34
  • 1
    jQuery doesn't really handle "XML". It uses the browser to interpret markup via the "innerHTML" mechanism. Thus, what you're giving it is interpreted as HTML, like it or not. Anything in there that looks like a **real** HTML tag is going to be treated the same way it would be if you dropped it in your page markup. If it's in a weird place, relative to where it's supposed to be (like an ` – Pointy May 25 '10 at 22:56

3 Answers3

9

Update

jQuery has this method built-in now. You can use

$.parseXML("..")

to construct the XML DOM from a string.


jQuery relies on the HTML DOM using innerHTML to parse the document which can have unreliable results when tag names collide with those in HTML.

Instead, you can use a proper XML parser to first parse the document, and then use jQuery for querying. The method below will parse a valid XML document in a cross-browser fashion:

// http://www.w3schools.com/dom/dom_parser.asp
function parseXML(text) {
    var doc;

    if(window.DOMParser) {
        var parser = new DOMParser();
        doc = parser.parseFromString(text, "text/xml");
    }
    else if(window.ActiveXObject) {
        doc = new ActiveXObject("Microsoft.XMLDOM");
        doc.async = "false";
        doc.loadXML(text);
    }
    else {
        throw new Error("Cannot parse XML");
    }

    return doc;
}

Once the XML DOM is constructed, jQuery can be used as normal - http://jsfiddle.net/Rz7Uv/

var text = "<root><option>cow</option><option>squirrel</option></root>";
var xml = parseXML(text);
$(xml).find("option"); // selects <option>cow</option>, <option>squirrel</option>
Anurag
  • 140,337
  • 36
  • 221
  • 257
  • Really useful answer. I ran into a similar problem when I was trying to append raw XML to a document with `$(pub.xmlDoc).find("publication > images").append("foo")` and "" was getting turned into "" What I did was use... `$(pub.xmlDoc).find("publication > images").append(DOMParser().parseFromString("foo","text/xml")` Note I'm taking a shortcut here and presuming not IE (which works for this application). – Tim Holt Jan 25 '12 at 01:27
  • @TimHolt - that's a neat approach, but this answer is old. jQuery has built-in the `parseXML` method which you can use. Let me update the answer. – Anurag Jan 25 '12 at 02:17
1

This is probably some special handling for the HTML <option> element, but I can't find that in the source.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • +1 - This is correct, I've seen the same thing with `` in XML, any valid html elements the browser may interfere with.
    – Nick Craver May 25 '10 at 22:28
1

On line 4448 of the unminified source for 1.4.2 is the culprit:

// ( div = a div node )
// ( elem = the xml you've passed to it )

div.innerHTML = wrap[1] + elem + wrap[2]; 

Consider this code:

var d = document.createElement('div');
d.innerHTML = "<foo><option>bar</option><b>blah</b></foo>";

alert(d.innerHTML); // <foo>bar<b>blah</b></foo>

// tested on Firefox 3.6

So, don't ask me why exactly, but it looks like something in the way the DOM handles it, not necessarily jQuery's fault.

Perhaps just use a different node name?

nickf
  • 537,072
  • 198
  • 649
  • 721
  • 3
    Just found that too. As far as I can tell, jQuery itself doesn't do any XML parsing whatsoever - it leverages "innerHTML" to convert a string into DOM nodes. Thus, it's not even XML that we're talking about: it's whatever you can convince the browser's HTML parser is valid markup. – Pointy May 25 '10 at 22:54