Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery Find() and XML does not work in IE

I am trying to use jQuery to parse an in-memory XML document. This works great in everything but IE (shocker). Some googling revealed that the problem is most likely due to the fact that IE is treating my document as HTML rather than XML MIME Type.

Is there a way to make my jQuery implmentation work or do I have to check the client browser and implement IE specific XML parsing?

Thanks!!

function getQAData(xmlData) {
var dataArr = new Array();
$(xmlData).find('item').each(function() {
    dataArr.push({ questionid: $(this).attr("cellID"), answer: $(this).find('answer').text() });
});

return dataArr; // this array is nice and populated in everything but ie

XML Sample

    <hwroot>
    <data pid="">
        <item cellID="24_951">
            <question>Are you there?</question>
            <answer>No</answer>
        </item>
        <item cellID="24_957">
            <question>A Question?</question>
            <answer>blah blah blah</answer>
        </item>
</data>
</hwroot>

Solution:

My jQuery .find() solution will not work for reasons described by @treeface below. Here is my solution:

Branch JS code based on navigator :(

  if (browserName == "Microsoft Internet Explorer") {
    MsXmlParse(xmlData, dataArr);

} else {
    $(xmlData).find('item').each(function() {
        dataArr.push({ questionid: $(this).attr("cellID"), answer: $(this).find('answer').text() });
    });
}

Definition of MsXmlParse

function MsXmlParse(xmlDocument, qarray) {
var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
xmldoc.async = "false";
xmldoc.loadXML(xmlDocument);

var itemElements = xmldoc.getElementsByTagName("item");

for (var i = 0; i < itemElements.length; i++) {
    var questionCellID = itemElements[i].getAttributeNode("cellID").nodeValue;
    var answerTxt = itemElements[i].childNodes[1].text;

    qarray.push({ questionid: questionCellID, answer: answerTxt });
}

} //end msxmlparse

like image 565
Nick Avatar asked Feb 14 '11 23:02

Nick


1 Answers

I'm not having any issues with this as you can see here:

http://jsfiddle.net/treeface/VuwcH/

My guess is that in IE, you're not parsing your XML data properly in the first place, but it's impossible to tell unless you show us the output of that xmlData variable. As you can see in my example, you need to use something other than the DOMParser object in order to parse an XML string properly in IE. You have to do this:

xmlData = new ActiveXObject("Microsoft.XMLDOM");
xmlData.async = "false";
xmlData.loadXML(text); //where text is your XML string

Edit:

OK, so is the problem here that your xmlData object is a string of XML? You mentioned in your post that it is "an in-memory XML document", in which case it would, and does, work in IE. As far as I can tell from your responses, xmlData is actually a string, and that's where the problems arise. IE is the only major browser that has issues with putting non-compliant HTML inside an HTML node. Since jQuery's XML parser wraps the supplied string in a div, it craps out in IE. jQuery recognizes this bug and they have considered it a "won't fix" issue.

Issue here: http://bugs.jquery.com/ticket/3143

Reason for not fixing: Check this link : http://api.jquery.com/jQuery#jQuery2 The jQuery constructor only supports html, not xml. The string is flushed into a div, that probably why IE blows up. Because the string isn't valid html.

Specifically this bit:

When the HTML is more complex than a single tag without attributes, as it is in the above example, the actual creation of the elements is handled by the browser's innerHTML mechanism. In most cases, jQuery creates a new <div> element and sets the innerHTML property of the element to the HTML snippet that was passed in. When the parameter has a single tag, such as $('<img/>') or $('<a></a>'), jQuery creates the element using the native JavaScript createElement() function.

When passing in complex HTML, some browsers may not generate a DOM that exactly replicates the HTML source provided. For example, Internet Explorer prior to version 8 will convert all href properties on links to absolute URLs, and Internet Explorer prior to version 9 will not correctly handle HTML5 elements without the addition of a separate compatibility layer.

So I suspect that they "won't fix" it because otherwise things would get sloppy for all other browsers. I'm not sure of the veracity of this answer (or the quality of the logic behind their decision) but that's the way it is.

So...in short (too late?)...no, there is no easy way to handle this in a single line. Then again, there also shouldn't be anything stopping you from using JSON instead of XML.

like image 86
treeface Avatar answered Sep 17 '22 18:09

treeface