Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Workaround for xml data islands

I recently inherited a huge webapp which is a combination of JSP,Javascript and Java. It works only on IE due to the way it has been coded using xml data islands and other things which prevent smooth functioning on other browsers. Everything was fine until a few days when Windows 7 boxes were rolled out for a few users in which IE9/10 has trouble with some of the javascript in the application. For example, the following data island is a snippet from my html page.

<xml id = "underlyingdata" ondatasetcomplete="window.dialogArguments.parent.repopulateDropDown(this, underlyingdd)">
</xml>
<xml id="termdata" ondatasetcomplete="window.dialogArguments.parent.repopulateDropDown(this, termdd)">
</xml>

On this page there is another line of code

window.dialogArguments.parent.request(underlyingdata, "CONTRACT.LIST.WB", "PULP AND PAPER|" + instrumentdd.options[instrumentdd.selectedIndex].text);

that calls a function which is as follows

function request(xmldataisland, requestmethod, parameters
{       
    var screwcache=Math.round(Math.random()*10000);
    xmldataisland.value=null;
    xmldataisland.load("/webaccess/Request?sessionid=" + sessionid + "&request=" + requestmethod + "&parameters=" + parameters+"&screwcache="+screwcache);

}

This fails in IE9/10 with the error that 'load' is not a valid method(Script 438 error) on 'xmldataisland' object, whereas it works perfectly fine on IE 5 to IE 8.

I believe the xmldataisland object in the above function is of type XMLDocument. Why does the load method fail? What is the workaround for this? I read and hear from many sources that using data islands is a terrible idea. What would be the correct alternative for this in that case?

like image 703
Sai Avatar asked Sep 11 '13 18:09

Sai


2 Answers

From IE10 onwards, XML data islands are no longer supported - the browser parses them as HTML. The Mozilla Developer Network have produced an article which gives a cross-browser alternative to XML data islands, namely an HTML5 "data block". The article demonstrates that a <script> element can be used as a data block if the src attribute is omitted and the type attribute does not specify an executable script type. You must also ensure that the embedded XML content doesn't include a </script> tag.

Source: https://developer.mozilla.org/en/docs/Using_XML_Data_Islands_in_Mozilla

Here's the HTML example they give...

<!DOCTYPE html>
<html>
<head>
<title>XML Data Block Demo</title>
<!-- this is the data block which contains the XML data -->
<script id="purchase-order" type="application/xml">
<purchaseOrder xmlns="http://example.mozilla.org/PurchaseOrderML">
  <lineItem>
    <name>Line Item 1</name>
    <price>1.25</price>
  </lineItem>
  <lineItem>
    <name>Line Item 2</name>
    <price>2.48</price>
  </lineItem>
</purchaseOrder>
</script>
<script>
function runDemo() {
  // the raw XML data can be retrieved using this...
  var orderSource = document.getElementById("purchase-order").textContent; 
  // the XML data can be parsed into a DOM tree using the DOMParser API...
  var parser = new DOMParser();
  var doc = parser.parseFromString(orderSource, "application/xml");
  var lineItems = doc.getElementsByTagNameNS("http://example.mozilla.org/PurchaseOrderML", "lineItem");
  var firstPrice = lineItems[0].getElementsByTagNameNS("http://example.mozilla.org/PurchaseOrderML", "price")[0].textContent;
  document.body.textContent = "The purchase order contains " + lineItems.length + " line items. The price of the first line item is " + firstPrice + ".";
}
</script>
</head>
<body onload="runDemo()";>
Demo did not run
</body>
</html>

You will need to write your own method to load data into that block (perhaps using jQuery.get or .load methods).

Hope that helps!

like image 96
w5m Avatar answered Sep 25 '22 05:09

w5m


4.5 years after the accepted answer was given, it's possible to do an update using HTML5. The script tag is not required. HTML5 is based on XML and allows you to make up your own tag-names. You can create an "xml island" for all browsers like so:

   <parms style="display:none;">
    <op>
       encrypt
    </op>
    <msg>
       Hello World!
    </msg>
  </parms>

And do something like this to use it.

  var xml = document.querySelector("parms");
  var op = xml.querySelector("op").textContent;
  var msg = xml.querySelector("msg").textContent;

You could also use a div (display:none) as a container for XML that is fetched using XHR. Since HTML5 is based on XML, you can return the XML from the server with MIME type text/XML and use .innerHTML to put it into the div.

like image 29
Roger F. Gay Avatar answered Sep 22 '22 05:09

Roger F. Gay