Kermit: XML über Ajax in Html/DIV nachträglich einbauen

Hi,

ich bin ein Newbie was DOM Model und Verarbeitung von XML mit JavaScript betrifft. Sorry falls meinen folgenden Fragen möglicherweise dumm klingt.

Ich habe bis jetzt geschafft eine XML Seite mittels Ajax nachzuladen.
Nun steht die Information in transport.responseXML und transport.responseText.
Ich kann es mit alert ausgeben.

Ich möchte jetzt folgendes erreichen:

  1. den XML parsen um daraus einige Informationen in Javascript Variablen abspeichern.
  2. den responseText in ein ,in der Seite befindliches, DIV Element ausgeben.

Gibt es für 1) einen einfacheren XML-Parser mit dem ich an meine Informationen innerhalb des XML Objekts rankomme. Mit DOM Zugriffe tue ich mir sehr schwer, oder eine ausführliche Doku dazu würde auch helfen.

Zur 2) wie wandle ich XML in einer Tabelle um so das ich anschließend alles innerhalb von DIV einbauen kann (mit innerHTML). Gibt es auch andere Möglichkeiten?
Einfach den XML Objekt im innerHTML zu schreiben funktioniert nicht.

vielen Dank für eure Hilfe
Kermit
PS: mein xml sieht wie folgt aus:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE XRF SYSTEM "/xxx.dtd">

<XRF r="1.22" c="asd" g="we" u="xyz" k="" d="2009" t="143231">
<A k="asd" n="3" v="123"/>
<A k="dse" n="3" v="234"/>
<A k="tz" n="3" v="456"/>

</XRF>

    1. den XML parsen um daraus einige Informationen in Javascript Variablen abspeichern.

    Geparst ist das XML-Dokument schon - nämlich in eine DOM-Struktur unter responseXML.

    Dir bleibt nichts anders übrig, als damit zu arbeiten. Wenn dir das nicht gefällt, was ich gut verstehen kann, solltest du zu einem geeigneterem Format wie JSON umsteigen. Diese Daten lassen sich in JavaScript viel einfacher verarbeiten. XML ist da m.E.n. nur in seltenen Fällen sinnvoll.

    Gibt es für 1) einen einfacheren XML-Parser mit dem ich an meine Informationen innerhalb des XML Objekts rankomme. Mit DOM Zugriffe tue ich mir sehr schwer, oder eine ausführliche Doku dazu würde auch helfen.

    Für XML-Dokumente gilt im Grunde das, was man auch von HTML-Dokumenten kennt.
    Z.B. <http://de.selfhtml.org/javascript/objekte/node.htm@title=die Node-Eigenschaften und -Methoden> und Methoden wie http://de.selfhtml.org/javascript/objekte/document.htm#get_elements_by_tag_name@title=getElementsByTagName.

    Mal ein Beispiel:

    var xmlDoc = xmlhttprequest.responseXML;  
      
    // Attribut beim XRF-Element (Wurzelelement) auslesen  
    var xrfElement = xmlDoc.documentElement;  
    alert( xrfElement.getAttribute('r') ); // da hast du ja viele von  
      
    // Alle A-Elemente in einen Array überführen:  
    var aData = [];  
    var aElements = xmlDoc.getElementsByTagName('A');  
    for (var i = 0, aEl; aEl = aElements[i]; i++) {  
       // Object (Hash) mit den Attributwerten erstellen und an den Array anhängen  
       aData.push({  
          k : aEl.getAttribute('k'),  
          n : aEl.getAttribute('n'),  
          v : aEl.getAttribute('v'),  
       });  
    }  
      
    // Auf Array zugreifen, v-Eigenschaft auslesen  
    alert( aData[0].v );
    

    Zur 2) wie wandle ich XML in einer Tabelle um so das ich anschließend alles innerhalb von DIV einbauen kann (mit innerHTML).

    Im Prinzip wie oben die Elemente heraussuchen, mit einer Schleife durchlaufen, die Daten herausholen (z.B. mit getAttribute).

    Anhand dessen kannst du dann einen String mit HTML-Code zusammenbauen. Den schreibst du letztlich mit innerHTML in ein Element.

    var htmlString = '<table> <caption>A-Elemente</caption> <thead> <tr> <th>k</th> <th>n</th> </tr> </thead> </tbody>';

    var aElements = xmlDoc.getElementsByTagName('A');  
    for (var i = 0, aEl; aEl = aElements[i]; i++) {  
       // Code für Tabellenzeile generieren und anhängen  
       htmlString += '<tr>' +  
          '<td>' + aEl.getAttribute('k') + '</td>' +  
          '<td>' + aEl.getAttribute('n') + '</td>' +  
          '<td>' + aEl.getAttribute('v') + '</td>' +  
          '</tr>';  
    }  
    htmlString += '</tbody></table>';  
      
    document.getElementById('beispielID').innerHTML = htmlString;
    

    Mathias

    1. Danke Mathias,

      Ich habe nach eine dynamische Lösung (rekursion) die alle xml Formate einlesen kann unabhängig von der Tiefe außerdem sollte das ausgegebene xml wie beim Mozilla zu/aufklappbar.
      Ich habe auch nichts weiteres gefunden musste also eigene Klassen dafür schreiben.
      Rausgekommen ist eine Klasse MyXml die nach der Instantierung( "new MyXml(transport.responseXML)" ) eine Funktion zur Verfügung sellt ( "parse2html" )
      mit dem man das XML Onject in HTML Text umwandeln kann (TABLE oder DIV).
      Die Funktion erwartet 2 Parameter:

      • nr 1: xml Child ab wo die Ausgabe erfolgen soll. Man muss also nicht den kompletten Baum anzeigen.
      • nr 2: Ausgabeformat als html Tabelle oder mit div's analog xml Ansicht in Mozilla.

      Hier ist mein Ergebnis für anderen die auch sowas brauchen können.
      Wiel spass damit. Es ist möglicherweise nicht die schönste Lösung aber es funktioniert.

      den Ajax Teil:
      new Ajax.Request(url, { method:'get',
          onSuccess: function(transport){
      var xmlData = new MyXml(transport.responseXML);
      $(divContent_1).innerHTML( xmlData.parse2html('A','TABLE') );
      $(divContent_2).innerHTML( xmlData.parse2html('XRF','DIV') );
          },
          onFailure: function(){},
          onUninitialized: function(){},
      onLoading: function(){},
      onLoaded: function(){},
      onInteractive: function(){},
      onComplete: function(){},
      onException: function(){}
      });

      ##############################################
      // Die Klassen über eine .js Datei laden
       *-------------------------- Class MyObject -----------------------------*/

      var MyObject = Class.create({
        initialize: function(varName) {
          this.varName = varName;
        },
        toString: function() {
          return this.getObject(this, this.name, '');
        },
        showDebug: function() {
          document.write( this.getObject(this, this.name, 'html') );
          return ;
        },
        getContent: function() {
          return 'empty MyObject';
        },
      getObject: function(MyObject, name, mode) {
      sOut = '';

      	if (mode == 'html') {  
        	sOut = sOut+"<table border='1'>\n";  
        	sOut = sOut+"  <tr>\n";  
        	sOut = sOut+"		 <td colspan='3'><b>'"+name+"' properties:</b></td>\n";  
        	sOut = sOut+"	 </tr>\n";  
        	for (var item in MyObject) {  
        		sOut = sOut+"<tr>\n";  
        		sOut = sOut+"  <td>&nbsp;</td>\n";  
        		sOut = sOut+"  <td valign='top'>"+item+": </td>\n";  
        		sOut = sOut+"  <td>"+this.newline2br(MyObject[item])+"</td>\n";  
        		sOut = sOut+"</tr>\n";  
        	}  
        	sOut = sOut+"</table>\n";  
        } else {  
        	sOut = sOut+"'"+name+"' properties:\n";  
        	for (var item in MyObject) {  
        		sOut = sOut+item+":";  
        		sOut = sOut+"  "+MyObject[item]+"\n";  
        	}  
        }  
        return sOut;  
      },  
      newline2br: function(sTmp) {  
      	var sInt = ""+sTmp;	  
      	var sOut = sInt.replace(/\n/g, "<br>&nbsp;&nbsp;");  
      	return sOut;  
      }  
      

      });
       *--------------------- class MyXml ----------------------------*/

      function x(e) {
      if (e.parentNode.className != 'expander-closed') {
      e.parentNode.className = 'expander-closed';
      e.innerHTML = '+';
      } else {
      e.parentNode.className = 'expander-open';
      e.innerHTML = '-';
      }
      return true;
      }

      var MyXml = Class.create(MyObject, {
        initialize: function($super,xmlObj) {
         $super('xmlObj');
         this.debug = false;
         this.XMLDocument = xmlObj;
         this.maxColSpan = 0;
      if (this.debug) alert('002: MyXml.initialize');
        },
        setDocument: function( newXmlObj ) {
         this.XMLDocument = newXmlObj;
          return ;
        },
      calcColspan: function(oParent, iColSpan ) {
         var iTmp = iColSpan+1;
         if ( this.maxColSpan < iTmp ) {
         this.maxColSpan = iTmp;
         }
         var iChd = oParent.childNodes.length;
         for (var i=0; i<iChd; i++ ) {
         this.calcColspan( oParent.childNodes[i],iTmp );
         }
         return;
      },
        getDocument: function( newXmlObj ) {
         return this.XMLDocument;
        },
        parse2html: function( tagName, sView ) {
         var sOut = '';
      if (this.debug) alert('003 MyXml.parse2html -> tagName:'+tagName);
        
         var data = this.XMLDocument.getElementsByTagName(tagName);
        
         var iTag= data.length;
      if (this.debug) alert('003 MyXml.parse2html -> iTag:'+iTag);
         for ( var i=0; i<iTag; i++ ) {
         this.calcColspan( data[i],0 );
         }
         for ( var i=0; i<iTag; i++ ) {
         sOut = sOut+this.child2html( data[i],-1,data[i].nodeName,sView );;
         }
        
         if ( sOut != '' ) {
         if ( sView == 'TABLE' ) {
         sOut = '<table border="1">'+sOut+'</table>';
         } else {
         sOut = sOut;
         }
         }
        
      if (this.debug) alert('003 MyXml.parse2html -> sOut:'+sOut);
         return sOut;
        },
      child2html: function(oParent, iSpan, sTmp, sView ) {
         var sOut = '';
         iSpan++;
        
         var iChd = oParent.childNodes.length;
      if (this.debug) alert('003-1 child2html -> nodeName:'+oParent.nodeName+' nodeType:'+oParent.nodeType+'\n sTmp:'+sTmp+' iChd:'+iChd);
         var sChd = '';
         for (var i=0; i<iChd; i++ ) {
         var sTmp2 = sTmp+'->'+oParent.childNodes[i].nodeName;
         sChd = sChd+this.child2html( oParent.childNodes[i],iSpan,sTmp2,sView );
         }
         if ( sView != 'TABLE' && oParent.nodeType != 3 && this.maxColSpan-iSpan > 1 ) {
         sChd = '<div class="expander-content">\n'+sChd+'</div>\n';
         }
        
         var sAtr = '';
        if ( oParent.nodeType != 3 && oParent.attributes.length > 0 ) {
         sAtr = this.attrib2html( oParent );
        } else if ( oParent.nodeType != 3 ) {
         sAtr = '&lt;<span class="start-tag">'+oParent.nodeName+'</span>&gt;\n';
        }

        if ( sAtr != '' ) {  
        	if ( sView == 'TABLE' ) {  
        		sAtr = '<tr>'+this.getTdSpan(iSpan)+'<td colspan="'+(this.maxColSpan-iSpan)+'">'+sAtr+'</td></tr>';  
        	}  
        }  
        
        sOut = sOut+sAtr;  
        sOut = sOut+sChd;  
        if ( sView != 'TABLE' && oParent.nodeType != 3 && iChd > 0 ) {  
        	var sTmpDivs	= '<div class="expander" onclick="x(this);">-</div>\n';  
        	if (  iSpan != 0 && (this.maxColSpan-iSpan ) >= 2 ) {  
        		sTmpDivs = '<div class="expander-open">\n'+sTmpDivs;  
        	}  
        	sOut = sTmpDivs+sOut+'\n';  
        } else if (  sView != 'TABLE' && oParent.nodeType != 3 && iChd == 0 ) {  
        	sOut = '<div>'+sOut+'</div>\n';  
        }  
        
        if ( iChd > 0 ) {  
        	if ( sView == 'TABLE' ) {  
        		sOut = sOut+'<tr>'+this.getTdSpan(iSpan)+'<td colspan="'+(this.maxColSpan-iSpan)+'">&lt;/<span class="start-tag">'+oParent.nodeName+'</span>&gt;</td></tr>\n';  
        	} else {  
        		if ( iSpan == 0 ) {  
        			sOut = sOut+'&lt;/<span class="end-tag">'+oParent.nodeName+'</span>&gt;\n';  
        		} else {  
        			sOut = sOut+'&lt;/<span class="end-tag">'+oParent.nodeName+'</span>&gt;\n</div>\n';  
        		}  
        	}  
        }  
      

      return sOut;
      },
      attrib2html: function( oParent ) {
         var sOut = '';
        
         var sNode = '';
         var nodeName = oParent.nodeName;
         var iAttr = oParent.attributes.length;
         var attName = '';
         var attVal = '';
        
         sNode = sNode+'&lt;<span class="start-tag">'+nodeName+'</span>';
         for ( j=0; j<iAttr; j++ ) {
         attName = oParent.attributes[j].nodeName;
         attVal = oParent.attributes[j].nodeValue;
         sNode = sNode+' <span class="attribute-name">'+attName+'</span>="<span class="attribute-value">'+attVal+'</span>"';
         }
         if ( oParent.childNodes.length > 0 ) {
         sNode = sNode+'&gt;\n';
         } else {
         sNode = sNode+'/&gt;';
         }
        
         sOut = sOut+sNode;
         return sOut;
      },
      getTdSpan: function( iSpan ) {
      var sOut = '';

      	for ( var i=0; i<iSpan; i++ ) {  
      		sOut = sOut+'<td>&nbsp;</td>';  
      	}  
      	  
      	return sOut;  
      }  
      

      });

      ################# style.css ########################
      @import "resource://gre/res/viewsource.css";

      #header {
      background-color:#CCCCCC;
      border-bottom:3px solid black;
      margin-bottom:1em;
      padding:0.5em;
      }

      .expander-content {
      padding-left:1em;
      }

      .expander {
      -moz-user-select:none;
      cursor:pointer;
      display:inline-block;
      margin-left:-1em;
      text-align:center;
      vertical-align:top;
      width:1em;
      }

      #top .expander-open, #top .expander-closed {
      margin-left:1em;
      }

      .expander-closed .expander-content {
      display:none;
      }

      .comment {
      font-family:monospace;
      white-space:pre;
      }