3

Possibly odd question; I'm trying to load an XML into jQuery to traverse it.

Using $.post I can do this perfectly, and specify XML as the dataType. My question revolves around how I can get jQuery to use that dataType to understand the same data if it is already in the page, i.e. I have it in a variable.

Whenever I use exactly the same XML data in a variable it can't traverse it properly.

I've tried taking out the declaration and removing question marks, escaping quotes etc.

I've tried loading like:-

var xml = new XML('<blah><moo>134</moo></blah>');

and of course

var xml = $('<blah><moo>134</moo></blah>');

and

var xml = '<blah><moo>134</moo></blah>';

and

var xml = "<blah><moo>134</moo></blah>";

etc. What am I doing wrong?

waxical
  • 3,826
  • 8
  • 45
  • 69
  • +1 I've never heard of doing this before but I can see how it would be a useful feature. – Jake Jan 26 '11 at 18:50
  • Can you show the code you're using to traverse the XML string? – Jake Jan 26 '11 at 18:56
  • Try this: http://stackoverflow.com/q/1290321/273816 – chprpipr Jan 26 '11 at 18:57
  • There's tonnes of code traversing the string; which as I say was successful and error free in post'd var. "var foobar = $(xml).find('cows').children();" for example... It does now appear as though (unless firebug is lying I'm getting the infamous "unterminated string literal" - and it appears as though it's cut off. Which suggests the XML is too long? Possible? Not sure again, why it's different to post/ajax processed version. – waxical Jan 26 '11 at 19:13
  • What's the problem? It works for me: http://jsfiddle.net/zkVvf/ – gen_Eric Jan 26 '11 at 22:07
  • 1
    We've discovered a bit more about the problem. Yes, Rocket... the code does work there, however putting our (large) xml in and traversing EMPTY nodes failed. I.e. I was getting a value from a node that had no value. This seemed to point to the issue; that jQuery post/ajax does SOMETHING to the XML to weed out things it knows jQuery stumbles over. We've been weeding and weeding out, but are still encountering problems with objects created by the XML data. IF ANYONE KNOWS of a sort of run down/schematic of what jQuery do with an xml in dataType processed post/ajax it'd really help. – waxical Jan 27 '11 at 14:54
  • 3
    Maybe related (fixed in jQuery 1.5): http://bugs.jquery.com/ticket/6693 – Heikki Jan 31 '11 at 14:59
  • Thanks, Heikki. It seems similar and I tried it, but to no avail. Will keep it to 1.5 for now though to eliminate possibility. – waxical Feb 01 '11 at 13:13
  • I've tried jQuery 1.5's new `parseXML()` method and it worked fine for me: `var xmlDoc = $.parseXML("134");` – Tim Down Feb 02 '11 at 10:51

3 Answers3

3

The problem is that jQuery doesn't parse XML, except using the built-in browser responseXML property of XMLHttpRequest when doing Ajax requests. If you pass an XML string to $(), it simply assumes it's HTML, assigns it as the innerHTML of an HTML element and reads the children of that HTML element. This is not XML parsing.

To parse XML, you can use a function like the following:

var parseXml;

if (window.DOMParser) {
    parseXml = function(xmlStr) {
        return ( new window.DOMParser() ).parseFromString(xmlStr, "text/xml");
    };
} else if (typeof window.ActiveXObject != "undefined" && new window.ActiveXObject("Microsoft.XMLDOM")) {
    parseXml = function(xmlStr) {
        var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(xmlStr);
        return xmlDoc;
    };
} else {
    parseXml = function() { return null; }
}

var xml = parseXml("<blah><moo>134</moo></blah>");
if (xml) {
    window.alert(xml.documentElement.nodeName);
}

UPDATE

jQuery 1.5's new parseXML() method does exactly this, and seems to work well.

var xml = $.parseXML("<blah><moo>134</moo></blah>");

This gives you an XML document, which you can then traverse using jQuery in the usual way:

var $xml = $(xml);
alert($xml.find("moo:first")[0].nodeName);
Tim Down
  • 318,141
  • 75
  • 454
  • 536
2

Here is a sample that uses $.ajax and works cross browser (well Chrome, IE8, FireFox 3.6):

var pathToXML = "http://www.site.com/data/data.xml";
var xml;
    $.ajax({type: "GET", 
            url: pathToXML,
            cache: false, 
            dataType: ($.browser.msie) ? "text" : "xml",
            error: function(XMLHttpRequest, textStatus, errorThrown){alert(textStatus)},
            success: function(data){
            // workaround for msie
            if (typeof data == "string") {
                    xml = new ActiveXObject("Microsoft.XMLDOM");
                    xml.async = false; xml.loadXML(data);
            } else { xml = data; }
            xml.setProperty("SelectionLanguage", "XPath");
            // end workaround
            // use $(xml).find('node').text();
            var bobsNodeValue = $(xml).find("node[id='bob']").text();
    }});

This also sets it up as actual XML, which jQuery can traverse like a normal DOM tree using .find() and .text().

EDIT:: Just read through the new comments to the question. Can you post an example of the failed xml here? Also, using .html() will probably result in errors whereas .text() should return a blank string for empty nodes.

EDIT EDIT:: Here is a fiddle showing no errors, what code are you using to traverse and is it all browsers or just a particular one?

WSkid
  • 2,736
  • 2
  • 22
  • 26
  • Ok, so we have:- - When it gets to the it's failing. As I say, this does not fail with $.post. – waxical Feb 01 '11 at 10:44
  • Added a fiddle showing that it returns empty, what code are you using to traverse that string as I think I am focusing in the wrong direction. – WSkid Feb 02 '11 at 04:56
0

You tried to urlencode the xml before sending it to jQuery?