Make XML data islands work in Mozilla

XML data islands offer a useful way to add dynamic data to static HTML pages, but they are typically limited because they work only in IE. See how you can get around this by writing some complex JavaScript and implementing them in Mozilla.

Recently, I wrote an article on the virtues of XML data islands and, although the article was well received, a number of readers pointed out that XML data islands work only with Microsoft Internet Explorer. Because of this platform limitation and possibly because data islands were developed by Microsoft, XML data islands are doomed to remain on the nonstandard tool pile for now. Thankfully, this exile should last only until another browser can handle XML data islands. So, armed with a copy of Mozilla, a good knowledge of JavaScript, and a real loose grip on reality, I decided to take matters into my own hands and provide a way for Mozilla to process XML data islands.

Because of time constraints, I decided to limit the scope to the following features of data islands, which cover about 95 percent of the current uses:
  • ·        Binding non-tabular HTML INPUT tags to XML nodes
  • ·        Binding non-tabular HTML DIV tags to XML nodes
  • ·        Binding non-tabular HTML SPAN tags to XML nodes
  • ·        Binding HTML TABLE tags to XML data islands
  • ·        Binding tabular HTML INPUT tags to XML nodes
  • ·        Binding tabular HTML DIV tags to XML nodes
  • ·        Binding tabular HTML SPAN tags to XML nodes

To sum it up: Change the value of an HTML INPUT object, and the corresponding XML node's value changes. Although, at first glance, giving Mozilla XML data island support seems like wizardry, it is accomplished through the use of cascading style sheets (CSS), JavaScript, and the HTML Document Object Model Level 1.

Getting started
Because Mozilla does not have integral XML data island support, when presented with XML, it will do its best to render the text. So, unless measures are taken, a data island like the ones shown in Listing A will be displayed as shown in Figure A. This is where CSS comes into play. You can implement CSS to hide the data island's XML (Listing B). The rest of the process is handled through a combination of JavaScript and DOM.

Figure A

Even though Mozilla does not provide a specific way to handle XML, it does provide a way to address parts of an HTML document and thus to access the data island: via the DOM. For example, coding document.getElementsByTagName('xml') results in a collection consisting of all XML nodes and descendents. Node attributes, like id, can be retrieved as with document.getElementsByTagName('xml').item(0).getAttribute('id'). This method can also be used to access the bound HTML nodes. This ability to access nodes and attributes is key in finding both the data islands and the associated HTML nodes.

JavaScript is used to control flow and to create objects used in the binding of the XML nodes and HTML nodes. Controlling the flow is preventing Internet Explorer from executing this code, looping through the DOM, and setting an onchange event handler for all of the bound HTML INPUT elements.

The first of these JavaScript objects is the collection object, which is used three times. First, it stores XML data islands using their name prefixed with (datasrc). The second use of the collection object is to store the bound HTML nodes. An instance of the JavaScript object shown in Listing C is stored in the collection. The third use is to ensure that instances of each datafld are unique, which enables the counting of table rows.

The object shown in Listing C provides a way to access bound nodes and to differentiate between tabular and non-tabular nodes. For example, non-tabular entries for HTML DIV tags will have both a datasrc and a datafld, while tabular entries for HTML DIV tags have an entry only for datafld. In the case of the latter, the table specifies the datasrc. The node is used to ensure that the correct node is being processed, and the nodeName is used to distinguish the various types of nodes.

Processing an XML data island in Mozilla starts with finding the individual XML tags and storing them in a collection. Next, the bound table tags (those with a datasrc attribute) and their bound child nodes are processed. Finally, the stand-alone bound INPUT, DIV, and SPAN tags are handled.

Because HTML INPUT tags permit the modification of their associated values, they require the addition of an onchange event handler to update the corresponding XML node and redisplay any HTML nodes that may be bound to it. To avoid making this more complex than necessary, the redisplay is handled by simply rebinding the XML data island and the various HTML tags. The resulting code is the JavaScript function shown in Listing D in this downloadable code snippet.

Care and feeding of Mozilla XML data Islands
To invoke the MozillaDSO() function, you just need to add an onload event handler to the page's body tag, as shown in the complete example, Listing E (also in the downloadable code snippet). Once this has been accomplished, it really doesn't matter whether the client's browser is Internet Explorer or Mozilla. There is, however, one limitation to Mozilla data islands: Tags cannot close themselves. So, although <color></color> works, <color /> won't. Mozilla will insert a closing tag, usually where it will cause the most harm. In addition, you should ensure that the individual HTML node's onchange event handlers aren't overlaid with your own.


Editor's Picks