Javascript DOM

enrix

Mitglied
Hallo, ich möchte gern eine XML-Datei mit Javascript verarbeiten. Dazu brauche ich aus der folgenden XML-Datei die Knoten "b1".
Um auf das DOM zugreifen zu können habe ich mir dazu einen Einstiegspunkt geschaffen.
PHP:
var root =xmlDOM.getElementsByTagName("root")[0];

nun wollt ich mich durch den Baum hangeln so dass die Knoten mit dem Namen Betrag rausgefiltert werden. Zunächst wollte ich mir ein Array erzeugen das eine Referenz auf alle childNodes des root-Knoten enthält.
PHP:
var n = root.getElementsByTagName("b1");

Meine Frage ist nun, wie könnte ich alle <b1> -Knoten in ein Array stecken?

HTML:
<?xml version="1.0" encoding="UTF-8" ?>
<root>
	
	<a1>
		<b1>Aufgabe1</b1>	
		<c>
			<Punkt>
				<betrag>150</betrag>
				<jp>200</jp>
			</Punkt>
		
			<Punkt>
				<betrag>200</betrag>
				<jp>250</jp>
			</Punkt>	
		</c>		
	</a1>
	
	<a1>
		<b1>Aufgabe2</b1>	
		<c>
			<Punkt>
				<betrag>400</betrag>
				<jp>200</jp>
			</Punkt>
		
			<Punkt>
				<betrag>450</betrag>
				<jp>350</jp>
			</Punkt>	
		</c>		
	</a1>
			
</root>

Ich habe den folgenden Code probiert. Dieser soll mir zunächst eine Referenz auf alle <b1>-Knoten geben in form eines Arrays und anschließend möchte ich auf das Textelement zwischen den <b1>..</b1> Tags zugreifen.

PHP:
           							var root =xmlDOM.getElementsByTagName("root")[0];
          							var node= root.getElementsByTagName("b1");
          							
          							ausgabe.innerHTML=node[0].childNode.item(0).nodeValue;

also mein gedanke war, das der code nun Aufgabe1 als Text ausgeben sollte. Leider funktioniert das nicht.
 
Moin,

das sieht eigentlich alles ganz gut aus, ich würde sagen dein Problem beginnt hier:

Code:
ausgabe.innerHTML

InnerHTML ist keine DOM-Eigenschaft....verwende stattdessen DOM-Methoden wie bspw. appendChild(), um den Textknoten an der gewünschten Stelle einzufügen.

Schöner wäre natürlich, du verzichtest da auf JS und machst das mit XSLT.
 
Hallo,

du durchläufst dein DOM nicht wirklich, konsequenterweise sind Childnodes schonmal gar kein schlechter anfang, wenn du nun mit Schleifen arbeitest und das Ende mit hasChildnodes verknüpfst, kannst du relativ kompfortabel dein DOM durchlaufen und dabei ein Array füllen, oder das ganze auf dem Screen ausgeben oder whatever else.

zu dem Thema gibts auch zu Hauf Tutorials im Netz, mal abgesehen von der Objektreferenz auf http://www.selfhtml.org gibts genug rekursive Beispiele, mit denen du jedes x-beliebige XML Dokument parsen kannst, das sollt ja nun kein Problem sein, oder ;)

Greez

EDIT:// kaum isser wieder da, is der Sven schon wieder schneller :) Aber Recht hat er natürlich auch, fehlt ein wenig Basiswissen zum Thema
 
Die Funktion getElementsByTagName(NodeName); gibt Dir doch bereits eine NodeList zurueck. Diese nodeList entspricht deinem Array. Dann brauchst Du ja nur das Array durchgehen. Und wenn Du weisst, dass b1 nur ein Text-Element besitzt kannst Du auch node.firstChild.nodeValue verwenden.

Beispiel:
Code:
var list = xmlDOM.getElementsByTagName("b1");
for (var i=0;i<list.length; i++)
  alert(list[i].firstChild.nodeValue);
 
Danke für eure Hilfe. Habe den Code jetzt soweit angepasst und funktioniert soweit auch ganz gut. Das innerHTML habe ich wie besprochen entfernt und stattdessen appendChild benutzt. Zusätzlich habe ich Vorschlag von Chef_De_Loup umgesetzt. Der Inhalt wird nun nach dem ajax-prinzip aus der XML-Datei gelesen. Daher zeige ich euch meine onreadystatechange-funktion. Beim laden der Seite wird der Inhalt einer Selectbox automatisch aus einer XML-Datei herauf gefüllt.

PHP:
function sendRequest(){

	var req=getXMLHttpRequest();	
	if(req){
		req.onreadystatechange = function() {
    			if ((req.readyState == 4) && (req.status == 200)) { 								   					
           			var v_xml = req.responseText;
           			var xmlDOM;          
           			if(typeof ActiveXObject != "undefined"){
           				xmlDOM = new ActivXObject("Microsoft.XmlDom");
           				xmlDOM.loadXML(v_xml);
           			}else{
           				var parser =new DOMParser();
           				xmlDOM=parser.parseFromString(v_xml,"text/xml");
          			}         
           			var ausgabe =document.getElementById("Selbox"); // Die ID "Selbox" ist die Id einer Selectbox im HTML Dokument
           			
           			var list = xmlDOM.getElementsByTagName("b1");
					for (var i=0;i<list.length; i++){

						
						var node = list[i].firstChild.nodeValue;
          				var option = document.createElement('option');
      					option.text = node;
      					ausgabe.appendChild(option);

					}//end of for			      		  					
        		}//end of if							
		}//end of onreadystatechange = function()
		
		req.open("get","Datenbank/Aufgaben.xml",true); //hier wird die XML-Datei angegeben
		req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");		
		req.send(null);
	}// end of if(req)	
}

Cool wäre es natürlich wenn nun in einer zweiten selectbox ausschließlich die Inhalte ausgegeben die zwischen den <betrag>-Tags stehen und die zum jeweiligen <b1> tag
gehören, welches man in der ersten selectbox ausgewählt hat. Also wählt man in der ersten Select-box Aufgabe1 aus so erscheinen in der zweiten die Optionen 150 und 200. Ich forsche wie das funktioniert. Für Vorschläge bin ich sehr dankbar.

beste Grüße
Enrix
 
Ich empfehle das geparste DOM-Objekt als globale Variable abzulegen damit Du in den anderen Funktionen damit arbeiten kannst. Als Value Deines Option-Objektes uebergibts Du den Index des b1-Tags. Bei der OnChange-Funktion des Select-Feldes wird dann eine Funktion aufgerufen bei der Du den Value der gewaehlten Option uebergibst. Die Funktion sucht dann in dem b1-Tag nach Betraegen.

Code:
var xmlDOM = null;
function sendRequest()
{
 ...
 xmlDOM = parser.parseFromString(v_xml,"text/xml"); 
 ...
 for (var i=0;i<list.length; i++){
   var node = list[i].firstChild.nodeValue;
   var option = document.createElement('option');
   option.text = node;
   option.value=i;
   ausgabe.appendChild(option);
 }
 ...
}

function getBetrag(index)
{
  if (xmlDOM != null){
    b1node = xmlDOM.getElementsByTagName("b1")[index];
    betraglist = b1node.getElementsByTagName("betrag");
    for (...){
     .... // sollte ja jetzt klar sein wie es laeuft
    }
  }
}

Ich gehe jetz davon aus, dass bekannt ist wie man das Value an die Funktion uebergibt bei dem onChange-Aufruf des Select-Tags.
 
Hi,

vorsicht mit dem IE. Der wird bei folgender Passage wahrscheinlich Probleme haben:
Code:
for (var i=0;i<list.length; i++){
  var node = list[i].firstChild.nodeValue;
  var option = document.createElement('option');
  option.text = node;
  ausgabe.appendChild(option);
}//end of for

Besser:
Code:
for (var i=0;i<list.length; i++){
  var node = list[i].firstChild.nodeValue;
  ausgabe.options[ausgabe.options.length] = new Option(node, node);
}//end of for

Ciao
Quaese
 
Hab dazu noch eine kurze Frage. Ich wollte mir den Inhalt des b1-Tags auf folgender Art ausgeben lassen:
PHP:
		var list = xmlDOM.getElementsByTagName("a1");
			for (var i=0;i<list.length; i++){					
				var node = list[i].childNodes[0].childNodes[0].nodeValue;
          		var option = document.createElement('option');
      			option.text = node;
      			ausgabe.appendChild(option);
      		}//end of for

bekomme jedoch die Fehlermeldung:
PHP:
Result of expression 'list[i].childNodes[0].childNodes[0]' [undefined] is not an object.

auch wenn ich versuche den tag-namen zu ermitteln
PHP:
		var list = xmlDOM.getElementsByTagName("a1");
			for (var i=0;i<list.length; i++){					
				var node = list[i].childNodes[0].tagName;
          		var option = document.createElement('option');
      			option.text = node;
      			ausgabe.appendChild(option);
      		}//end of for
bekomme ich die Ausgabe
PHP:
undefined
wobei es für den parentNode funktioniert

was mache ich falsch bei der navigation durch das DOM?
 
Zuletzt bearbeitet:
Moin,

auch Textknoten sind ansich childNodes(ob auch Whitespaces als Textknoten angesehen werden, ist browserabhängig).

Du kannst sicherer per getElementsByTagName() auf b1 zugreifen.... diese Methode ist auch auf Knoten anwendbar:
Code:
var node = list[i].getElementsByTagName('B1')[0].nodeValue;

(Beachte, dass ich den TagName gross geschrieben hab....auch da gibt es je nach Browser Probleme, mit der Grossschreibung kann man diesen aus dem Weg gehen)
 
@ Quaese
ich habe das Programm nun für den Internet Explorer umgeschrieben. Allerdings scheint appendChild gar nicht zu funktionieren. Wie kann ich denn eine div box in das DOM der HTML-Seite einfügen sodass es keine Probleme mit dem IE gibt?

PHP:
var div_box= document.createElement("div");
 

Neue Beiträge

Zurück