Cross-Browser Javascript XML Parsing

47,758

Solution 1

The following will work in all major browsers, including IE 6:

var parseXml;

if (typeof window.DOMParser != "undefined") {
    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 {
    throw new Error("No XML parser found");
}

Example usage:

var xml = parseXml("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);

Live demo:

var parseXml;

if (typeof window.DOMParser != "undefined") {
    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 {
    throw new Error("No XML parser found");
}

var xml = parseXml("<foo>Stuff</foo>");
document.body.innerHTML = "Root element: " + xml.documentElement.nodeName;

Solution 2

Consider using jQuery.parseXML.

Note that old JQuery's code (pre 2.x) is essentially identical to one proposed in the accepted answer and can be found at http://code.jquery.com/jquery-1.9.1.js, partial version below:

// Cross-browser xml parsing
parseXML: function( data ) {
    ...
    try {
        if ( window.DOMParser ) { // Standard
            tmp = new DOMParser();
            xml = tmp.parseFromString( data , "text/xml" );
        } else { // IE
            xml = new ActiveXObject( "Microsoft.XMLDOM" );
            xml.async = "false";
            xml.loadXML( data );
        }
    } catch( e ) {
        xml = undefined;
    }
    ...
}

Starting JQuery 2.x code changed to skip ActiveX branch, if you still need it - use older version of JQuery or inline ActiveX parsing. Partial code from http://code.jquery.com/jquery-2.0.0.js:

// Cross-browser xml parsing
parseXML: function( data ) {
    var xml, tmp;
    .....
    // Support: IE9
    try {
        tmp = new DOMParser();
        xml = tmp.parseFromString( data , "text/xml" );
    } catch ( e ) {
        xml = undefined;
    }
    .....
},

Solution 3

If you need to parse large XML documents that you may not be able to completely hold in memory, consider using a SAX style parser like this one: https://github.com/isaacs/sax-js/

Share:
47,758
sazr
Author by

sazr

Updated on July 05, 2022

Comments

  • sazr
    sazr almost 2 years

    Are there any cross-browser / cross-platform ways to parse XML files in Javascript?

  • GotDibbs
    GotDibbs over 11 years
    jQuery.parseXml can be pretty slow. I would suggest looking at the post from @TimDown
  • GotDibbs
    GotDibbs over 11 years
    This works, except in IE9 in standards mode. In IE9 standards mode to correct the issue, you just need to reform your initial if statement to be something like: if (window.DOMParser && typeof XMLDocument !== "undefined")
  • Tim Down
    Tim Down over 11 years
    @GotDibbs: Really? The above example works fine for me in IE 9 standards.
  • GotDibbs
    GotDibbs over 11 years
    Yep. Not sure if there's some other setting getting in the way here, but the moment I go into the dev toolbar and switch the browser mode to IE9 and document mode to IE9 standards it bombs without that additional check.
  • zbstof
    zbstof over 11 years
    Maybe it was a year ago, but looking at the source code of jQuery (code.jquery.com/jquery-1.9.1.js), I fail to see the difference from the TimDown's answer (omitting some error-handling logic).
  • Tim Down
    Tim Down about 11 years
    @GotDibbs: I know it's been a while, but here's a jsFiddle that works fine for me in IE 9 standards mode: jsfiddle.net/3s7Ly/1
  • nhahtdh
    nhahtdh almost 9 years
    @TimDown: If it is a working version, would you mind editing that into your answer?
  • Tim Down
    Tim Down almost 9 years
    @nhahtdh: The code in the jsfiddle is exactly the same as in the answer. I haven't found the additional check to be necessary.
  • Bradley
    Bradley over 8 years
    @TimDown Is this code still reliable for all browsers (namely Chrome, Firefox, IE)? Or better still, is there a version of this code snippet that doesn't rely on ActiveX objects?
  • Tim Down
    Tim Down over 8 years
    @Bradley: DOMParser has now been standardized so this code shouldn't get any less reliable. It works in current versions of all major browsers. It only falls back to the ActiveX stuff in old versions of IE; if you don't care about those then you can remove the ActiveX code branch, but it won't do any harm if left in.
  • Alexei Levenkov
    Alexei Levenkov over 6 years
    @Zotov I've inlined your comment (post was rightfully downvoted as link-only, and your comment looked worth inlining rather than deleting the post).