Software by Steven

Sometimes a square peg is a round hole

Cross-browser XML Parsing with XmlHttpRequest

Ah yes, cross-browser coding. Easier now than it was when I first dabbled in JS, but I still get a major sense of satisfaction out of getting something working and working well. For my work on TTXT subtitling, I had to dig deep into the XmlHttpRequest class, edge cases on return types and ended up trying to figure out a way to handle everything on every browser known to man (well, at least the six I can test on). And I think I did it. How did I get here?

Working with an existing codebase I had some infrastructure to work with (and keep backwards-compatible so as not to break existing apps too) so it wasn’t remaking an entire wheel. Breaking wasn’t much of an issue though, their library has a great modular design so it’s fairly easy to add stuff in, I just wanted to do it as elegantly as possible.

As TTXT is an XML document, I had to use the XmlHttpRequest.responseXML property. But right away this was an issue: TTXT doesn’t have a MIME type of XML, but the W3C spec says that responseXML returns null if this is the case. What to do… other than use the overrideMimeType function! This handy function will force the request to be parsed as valid XML so that the responseXML property will return a DOM object.

But I was far from out of the woods yet. IE7 held Microsoft’s initial movement towards W3C-standard XmlHttpRequest, but the overrideMimeType function we need for this solution wasn’t implemented. So how to handle that? For that I had to look at the big picture.

Assuming we get our data back as an XML document, how do we want to handle and manipulate it? Traditional DOM traversal could be used thanks to DOM Level 2′s document.getElementByTagName function, though this is a bit typing to code and can be a little slow on the execution. John Resig does point out that “Native XPath is blazingly fast” and while there is potential for browser misimplementations of CSS selectors, something as trivial as getting elements by tag name seems like a good choice to use XPath for. This though… this means getting into more mucky browser-specific (or should I say, object-specific) coding. While Firefox 3.5, Firefox 4 beta 8, Chrome 6, Chrome 7 beta, Safari 5 and Opera 10 all can be handled using document.evaluate the same way, IE (at least IE8 and below) requires the loading and calling of ActiveX Code.

So in the end, the only hang up is the Mime type, but being able to only override it in some browsers means having to resort to parsing it into a DOM tree in others (all the while being sure that both ways are done in an XPath-compatible way). Everything works up to this point except for retrieving an XML response as an XML DOM tree in some IE browsers. Turns out, as far as I can tell, that it just can’t happen. Luckily there’s a way in IE to parse a string as XML.

With all of these pieces together, it seems we have a bit of a mess of edge cases, what-if’s and work arounds. But not so:

XML Parse Flowchart

XML Parse Flowchart

And just like that, a high-level shot at a cross-browser way to integrate XML parsing with XmlHttpRequest. In implementation this came together for me through a series of closures and one class variable to allow for backwards compatibility, but for other applications this could be done with a single function.

5 Responses to Cross-browser XML Parsing with XmlHttpRequest

  1. Pingback: JavaScript: the nitty gritty | Syntax Error

  2. Pingback: TTXT Subtitling for BBB Video Player | Syntax Error

  3. Roman March 11, 2011 at 10:14 pm

    Hi Guys,

    I have created an article on my blog where I provide you a cross browser javascript solution for parsing the XML string, selecting nodes, selecting a single node, creating an empty xml, and others.

    You can see more details on my blog: http://extremedev.blogspot.com/2011/03/xml-parsing-and-other-xml-utilities.html

  4. Pingback: Converting a string to XML in JavaScript « Software by Steven

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.