innerHTML und XML und die AJAX-Lib Prototype

Puh - hab ich einfach nicht gewußt, dass der Microsoft Internet Explorer bei einer innerHTML-Zuweisung von einem XML-String schlapp macht...

Da probiere ich die AJAX-Lib Prototype aus und finde eine ganz interessante Funktionalität, nämlich den Ajax.Updater. Der fordert sich eine Datei vom Server an und hängt sie an ein mit einem id-Attribut ausgestattetes Element dran.

var ajax = new Ajax.Updater(element, url, options)

Eigentlich ganz einfach und schön. Sofort ausprobiert und im Firefox angesehen. Super! Dann das ganze im IE: schrecklich!!! Probiere alles hin und her. Nichts zu machen. Meine XML-File wollte sich nicht ordentlich anhängen lassen. Also hinein in den Scriptcode bei Prototype und die Stelle gesucht, wo das ganze passiert. Hmmm ... da wird die Datei entgegengenommen und zum String gemacht und mit innerHTML ans betreffende Element gehangen. Hmmm ... sollte da der Wurm drin sein? Schnell ein kleines Beispiel getestet und siehe da, Firefox macht aus dem XML-String ne schöne DOM-Struktur und der IE nicht!!! Mal sehen was andere dazu sagen. Jaja ... es geht im IE net.

Also bin ich nicht der einzige; es wird sicherlich was fertiges geben. Nö, nicht wirklich. Als wäre das nicht was schönes :) Anleitungen zum selbst stricken en masse. Mir bleibt wohl nichts übrig. Ach da steht es ja auch bei Prototype: der Ajax.Updater geht nur mit (X)HTML ... Hmm, und für XML? Nichts dabei. Da dachte ich, es wäre schön, aber ...

Die Lösung in einem kleinen Skript:

<style>
first_name {font-size:24px}
</style>
<div id="a1">hallo</div>
<script>
function loadXMLstring(xmlstr) {
if (typeof DOMParser == "undefined") {
  var xml = new ActiveXObject("Microsoft.XMLDOM");
  xml.loadXML(xmlstr);
  domTree(xml.firstChild,document.getElementById("a1"));
  }
else {
  document.getElementById("a1").innerHTML += xmlstr;
  }
alert( document.getElementById("a1").innerHTML);
}

function domTree(tree,position) {
  var e = document.createElement(tree.nodeName);
  position.appendChild(e);
  if (tree.nodeValue) e.innerHTML=tree.nodeValue;
  for (var i=0; i<tree.attributes.length; i++) {
      var a = document.createAttribute(tree.attributes[i].nodeName);
      a.nodeValue = tree.attributes[i].nodeValue;
      e.setAttributeNode(a);
      }
  if (tree.hasChildNodes()) {
      for (var i=0; i<tree.childNodes.length; i++) 
         if (tree.childNodes[i].nodeName != "#text")
            domTree(tree.childNodes[i],e);
      }
}
</script>
<a href='javascript:loadXMLstring("
<customer pu=\"a1\" pa=\"123\">
<first_name>Joe</first_name>
<last_name id=\"4711\">Smith</last_name>
</customer>
")'>CLICK</a>

Ganz am Anfang der style-Tag ist nur zum Formatieren des XML. Dann das Element, an den der XML-String eingehangen wird mit der Id="a1". Die Funktion loadXMLstring(xmlstr) wird aus einem <a>-Element aktiviert und unterscheidet brav, ob es sich um IE oder Firefox handelt (weitere Browser hab ich nicht, also gibts dazu auch nichts). Beim else-Zweig sieht man, wie einfach man es sich beim Firefox machen kann. Der IE-Zweig lädt den XML-String in ein XML-DOM und ruft dann die Funktion domtree auf. Diese arbeitet den XML-String rekursiv ab, untersucht, ob die Elemente Inhalte und Attribute haben und hängt sie an das Browser-DOM dran. (Wer hierfür was besseres kennt, der soll mir mailen - hab leider keine Funktion bei Microsoft dafür gefunden ... auch sowas wie Nodecloning hat nicht funktioniert, aber vielleicht stell ich mich ja auch nur zu dumm an.) Irgendwie ist noch was nicht so schön beim Anhängen von TextNodes, da hab ich das gerade gebogen ... damit fallen die überfüssigen #text-Nodes weg.

Hab meine Prototype-Lib mit dieser Idee ergänzt und nun kann sie auch im Internet Explorer einen XML-Baum an ein Element meiner Wahl anhängen. Warum ist da noch keiner drauf gekommen? Was immer noch nicht schön ist, ist dass der Firefox die XML-Elemente brav und auch mit verbundenem style anzeigt und der IE nicht ...