XML String -> DOM
Niko
- javascript
Hi,
Ich versuche gerade aus einer XML Datei mittels Javascript ein paar Informationen auszulesen! Das funktioniert auch ganz gut, zumindest im Firefox 3 und Opera 9.5. Der IE macht leider wieder was er will:
Also mal Schritt für Schritt. Ich bekomme über AJAX einen String, der den Inhalt einer XML-Datei enthält. Daraus lösche ich erstmal den Kopf, also dieses <?xml .... ?> und versuche den restlichen String in einen DOM-Knoten umzuwandeln, indem ich zb. ein DIV-Element erzeuge, den String als innerHTML einfüge und dann die childNodes auslese.
function string2DOM(string)
var container = new Element('div', {
'html': string
});
//Whitespace entfernen
for (var i=0; i<container.childNodes.length; i++)
{
var node = container.childNodes[i];
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
node.dispose(); //Dispose ist ne Mootools Funktion, die das Element entfernt
}
if(container.childNodes.length == 1)
{
return container.childNodes[0].dispose();
}
else
{
var array = new Array();
for(var i = 0; i < container.childNodes.length; i++)
{
array.push(container.childNodes[i]);
}
}
return array;
}
Das Problem dabei ist, dass die XML-Datei nicht nur HTML-Gültige Tags, sondern auch sowas wie <layout> oder so enthält, die leider vom IE7 einfach nicht beachtet werden. Aus einem String:
<layout>
<markup>
<div>
<p></p>
</div>
</markup>
<layout>
wird beim IE
<div>
<p></p>
</div>
Gibt es irgendeine Möglichkeit das zu umgehen oder den String irgendwie anders in einen DOM Knoten zu verwandeln?
Mit der XML-Rückgabe von AJAX kann ich bis jetzt nichts anfangen, weil ich Mootools (http://www.mootools.net) verwende und die Element-Funktionen davon nur auf DOM-Elemente und nicht auf diese XML-Rückgabe funktionieren!
MfG Niko
Hallo,
ich weiß nicht, warum du das von hinten durch die Brust ins Auge löst.
Wenn du auf XML-Dokumente zugreifen willst, benutze das DOM. Dazu muss der Server die Antwort als application/xml senden, dann parst der Browser den XML-Code und hast du über die Eigenschaft responseXML des XMLHttpRequest-Objektes Zugriff auf den DOM-Baum. (Bei Mootools wird es ähnlich sein.)
Unsinnig hingegen ist es, den XML-Code in das bestehende HTML-Dokument einzufügen und dann zu versuchen, im HTML-DOM auf die eingefügten XML-Element Zugriff zu haben. Klar, dass das fehlschlägt.
Mit der XML-Rückgabe von AJAX kann ich bis jetzt nichts anfangen, weil ich Mootools (http://www.mootools.net) verwende und die Element-Funktionen davon nur auf DOM-Elemente und nicht auf diese XML-Rückgabe funktionieren!
Wo liegt das Problem? Wozu brauchst du Mootools-Funktionen und was hindert dich daran, direkt mit dem XML-DOM zu arbeiten?
Vielleicht solltest du dich auch mit JSON auseinandersetzen, einem für solche Datenübertragungen viel geeigneteres Format.
Mathias
ich weiß nicht, warum du das von hinten durch die Brust ins Auge löst.
Wenn du auf XML-Dokumente zugreifen willst, benutze das DOM. Dazu muss der Server die Antwort als application/xml senden, dann parst der Browser den XML-Code und hast du über die Eigenschaft responseXML des XMLHttpRequest-Objektes Zugriff auf den DOM-Baum. (Bei Mootools wird es ähnlich sein.)
Ok, also mal genauer: Die AJAX Anfrage geht direkt an eine XML-Datei, also header wär damit hoffentlich schonmal richtig! Das Problem ist, dass das zurückgegebene XML-Objekt vom Typ "IXMLDOMDocument2" (laut Visual Web Developer) ist und das Kinderelement, auf welches ich zugreifen will vom Typ "IXMLDOMElement" ist. Normale DOM Knoten (im HTML Dokument) sind wie ich das jetzt gesehen hab vom Typ "DispHTMLElement", wobei es da scheinbar noch ne Differenzierung zwischen den Elementen gibt.
Damit funktionieren sämtliche Mootools-Funktionen, die normalerweise auf den DOM Baum des HTML-Dokuments funktionieren auf dieses XML-Element nicht!
Wo liegt das Problem? Wozu brauchst du Mootools-Funktionen und was hindert dich daran, direkt mit dem XML-DOM zu arbeiten?
Also ich brauche sie nicht unbedingt, aber sie machen das Leben erheblich einfacher und ehe ich jetzt den ganzen Code verändere, alle Mootools Funktionen wieder rausnehme und durch Standard-Funktionen ersetze frag ich lieber hier, ob jemand ne Idee hat. ;)
Die wichtigste Funktion ist eigenlich Element.getElement/s, womit man mittels CSS-Selektor im DOM-Baum suchen kann.
Vielleicht solltest du dich auch mit JSON auseinandersetzen, einem für solche Datenübertragungen viel geeigneteres Format.
Normalerweise mach ich sowas auch mit JSON, aber hier geht es leider nicht nur um Dateiübertragung, sondern auch um die Übertragung eines DOM-Baumes (der im XML-Dokument definiert ist), welchen ich dann direkt (also nach ein paar Operationen darin) ins HTML-Dokument einfüge. (Wie man vlt schon am Tag Namen "Markup" erahnen konnte ;))
MfG Niko
Hallo,
Das Problem ist, dass das zurückgegebene XML-Objekt vom Typ "IXMLDOMDocument2" (laut Visual Web Developer) ist und das Kinderelement, auf welches ich zugreifen will vom Typ "IXMLDOMElement" ist. Normale DOM Knoten (im HTML Dokument) sind wie ich das jetzt gesehen hab vom Typ "DispHTMLElement"
Ja, klar. In dem XML-DOM hast du Zugriff auf dessen Element, wie es im DOM-Core beschrieben ist. Für HTML-Dokumente existiert noch ein genaueres, spezifischeres DOM, das ist das Kern-DOM plus HTML-Eigenheiten.
Damit funktionieren sämtliche Mootools-Funktionen, die normalerweise auf den DOM Baum des HTML-Dokuments funktionieren auf dieses XML-Element nicht!
Ja, das ist möglicherweise eine Dummheit von Mootools, oder aber du nutzt Methoden, die auch wirklich nur auf HTML-Elemente anwendbar sind.
Also ich brauche sie nicht unbedingt, aber sie machen das Leben erheblich einfacher und ehe ich jetzt den ganzen Code verändere, alle Mootools Funktionen wieder rausnehme und durch Standard-Funktionen ersetze frag ich lieber hier, ob jemand ne Idee hat. ;)
Höchstwahrscheinlich nicht.
Die wichtigste Funktion ist eigenlich Element.getElement/s, womit man mittels CSS-Selektor im DOM-Baum suchen kann.
Ich weiß ja nicht, wie kompliziert dein XML-Dokument ist, aber vielleicht kommst du schon mit getElementsByTagName ziemlich weit. Das ist nämlich auch im Core-DOM verfügbar.
.responseXML.getElementsByTagName("element")[x]
.responseXML.getElementsByTagName("element")[x].getElementsByTagName("unterelement")[y] usf.
Normalerweise mach ich sowas auch mit JSON, aber hier geht es leider nicht nur um Dateiübertragung, sondern auch um die Übertragung eines DOM-Baumes (der im XML-Dokument definiert ist)
HTML-Elemente in ein XML-Dokument direkt einzubetten hat eigentlich keine Vorteile. Du musst ohnehin mit der String-Serialisierung arbeiten, wie du es ja tust.
(Man könnte stattdessen den Knotenbaum einfach vom XML-DOM ins HTML-DOM herüberzukopieren, aber das kann der IE nicht.)
welchen ich dann direkt (also nach ein paar Operationen darin) ins HTML-Dokument einfüge.
Und wieso spricht das gegen JSON? Notierst du z.B. { html : "<p>Hallo Welt</p>" } und schreibst den Code mit innerHTML in ein bestehendes HTML-Element. Das geht am schnellsten, als wenn du in einem XML-String herumwurschtelst.
Ich weiß ja nicht, was du sonst noch für Daten hast, aber HTML-Code würde ich immer als String in einem JSON-Objekt übertragen. Damit kannst du auch alle in XML möglichen Strukturen abbilden und der Zugriff auf die Daten geht einfacher als über DOM.
Mathias
Hallo Mathias,
Danke für deine Hilfe! Ich habe es jetzt so gemacht, dass ich nur den Teil in ein HTML Element umzuwandeln, der auch wirklich HTML enthält! Der Rest bleibt XML bzw. wird in ein Objekt umgewandelt!
Ist vlt etwas umständlich, aber damit lässt sich meine Template.xml sehr schön und logisch strukturieren.
Lg Niko