Java DOM-Baum, spezielle Ausgabe

raffiSSL

Lt. Junior Grade
Registriert
Feb. 2006
Beiträge
289
Hallo, ich hab da mal wieder ein Problem mit Java. Jedoch liegt das Problem dieses mal irgendwo bei mir. Der Quelltext ist soweit richtig, aber er macht eben nicht das was ich will :)
Problematik: Ich soll mit Hilfe einer XML-Datei, welche ein Kochrezept beinhaltet entweder die Zuatatenliste, die Hilfsmittel oder die Zubereitungsbeschreibung ausgeben. Je nach Wahl des Nutzers also wird der Inhalt der Text-Knoten unter dem jeweiligen Element-Knoten ausgegeben.
Das Wurzelelement meiner XML ist kochen. Die Kinder dieses Wurzelelements sind zutaten, hilfsmittel und zubereitung.
Das Programm sieht folgendermaßen aus:

Code:
public class DOMAuswahl {
	
	SimpleInput in;
	
	public void suche (Node node, String ausw) {
		int i;
		String text = "";
		if (node.getNodeType() == Element.ELEMENT_NODE) {
			if (node.getParentNode() == null) {
				suche(node.getFirstChild(),ausw);
			}
			else {
				if (node.getNodeName().trim().equals(ausw)) {
					if (node.getNodeType() == Element.ELEMENT_NODE) {
						text = node.getNodeName()+": ";
						NodeList nl = node.getChildNodes();
						for (i = 0; i < nl.getLength();i++) {
							text += nl.item(i).getNodeName()+", ";
						}
					}
					else if (node.getNodeType() == Element.TEXT_NODE) {
						NodeList nl = node.getChildNodes();
						for (i = 0; i < nl.getLength();i++) {
							text += nl.item(i).getNodeValue()+", ";
						}
					}
				}
				else {
					if (node.getNextSibling() == null) {          
						System.out.println("Es hat geknallt!"); // wird immer ausgegeben wenn ich nicht "kochen" eingebe
					}
					else {
						suche(node.getNextSibling(),ausw);
					}
				}
			}
		}
		System.out.print(text);
	}
	
	public void go (String filename) throws ParserConfigurationException, SAXException, IOException {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse("Kochrezept.xml");
		Element root = doc.getDocumentElement();
		String ausw;
		in = new SimpleInput();
		System.out.println("Bitte geben Sie ein, was sie sehen möchten: ");
		System.out.println("Die Zutatenliste --> zutaten");
		System.out.println("Die Hilfsmittel --> hilfsmittel");
		System.out.println("Die Zubereitung --> zubereitung");
		ausw = in.readString("Auswahl: ");
		System.out.println("=============================================");
		System.out.println();
		suche(root, ausw);
	}
	
	public static void main (String args[]) throws ParserConfigurationException, SAXException, IOException {
		DOMAuswahl r = new DOMAuswahl();
		r.go("Kochrezept.xml");
	}
}

Das Programm gibt, sobald ich etwas anderes als "kochen" eingebe immer die println("Es hat geknallt!") aus. Aber warum?

Der Vollständigkeit halber noch die XML, welche validiert ist.

HTML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kochen SYSTEM "Kochrezept.dtd" >

<kochen>
       	<gericht>Nudelsalat</gericht>
	<zutaten xml:id="k1">
		<zutat>
			<name>Nudeln</name>
			<menge art="Gramm">500</menge>
		</zutat>
		<zutat>
			<name>Tomaten</name>
			<menge art="Gramm">500</menge>
		</zutat>
		<zutat>
			<name>Mozzarella</name>
			<menge art="Gramm">500</menge>
		</zutat>
		<zutat>
			<name>Zucker</name>
			<menge art="TL">1</menge>
		</zutat>
		<zutat>
			<name>Milch</name>
			<menge art="Milliliter">50</menge>
		</zutat>
		<zutat>
			<name>Salz</name>
			<menge art="TL">2-4</menge>
		</zutat>
	</zutaten>

	<hilfsmittel ref="k1">
		<bezeichnung>Schüssel</bezeichnung>
			<anzahl>2</anzahl>
		<bezeichnung>Löffel</bezeichnung>
			<anzahl>2</anzahl>
		<bezeichnung>Topf</bezeichnung>
			<anzahl>1</anzahl>
		<bezeichnung>Herdplatte</bezeichnung>
			<anzahl>1</anzahl>
		<bezeichnung>Messer</bezeichnung>
			<anzahl>1</anzahl>
	</hilfsmittel>
	
	<zubereitung>
	Nudeln bissfest kochen. Tomaten und Mozzarella kleinschneiden und mit den Nudeln in eine Schüssel geben.
	In eine extra Schüssel das Miracel Whip geben und mit etwas Milch verdünnen. Die TK-Kräuter, Salz, Pfeffer und Zucker hinzugeben.
	Wenn das Dressing soweit abgeschmeckt ist, kann es zu dem Nudelsalat gegeben werden. Gut umrühren und eine Nacht ziehen lassen.
	</zubereitung>
</kochen>

Ich hoffe das ist soweit verständlich.

mfg und danke :)
 
Zuletzt bearbeitet:
Du hangelst Dich nicht richtig runter im Baum. Am besten gehst Du das im Debugger mal durch, dann siehst Du, woran es hakt.

Zuerst landest Du ja im node "kochen".

if (node.getNodeName().trim().equals(ausw)
ist dann aber false, wenn Du nicht kochen eingibtst. Damit landest Du hier:

else {
if (node.getNextSibling() == null) {

getNextSibling holt aber einen Geschwisterknoten, keinen Kindknoten oder Tochterknoten. Es gibt aber parallel zu kochen keinen Knoten, darum "knallt" es.
 
Ich überprüfe aber ja ganz oben, ob der übergebene Knoten einen Elternknoten hat!? Da dies beim "kochen"-Knoten nicht der Fall ist, ruft er ja die "suchen"-Methode mit dem ersten Kindknoten auf. Erst dann kommt er weiter nach unten im Quelltext. oder etwa nicht?

mfg
 
Ich überprüfe aber ja ganz oben, ob der übergebene Knoten einen Elternknoten hat!? Da dies beim "kochen"-Knoten nicht der Fall ist, ruft er ja die "suchen"-Methode mit dem ersten Kindknoten auf. Erst dann kommt er weiter nach unten im Quelltext. oder etwa nicht?

Wie Toecutter schon geschrieben hat

if (node.getNextSibling() == null) {
System.out.println("Es hat geknallt!");
}
else {
suche(node.getNextSibling(),ausw);
}

ist das Problem.

"kochen" hat keine Geschwister nur Kinder.
Du bräuchtest hier einen foreach der für alle Kinder die suche Methode aufruft.
 
OK, ich weis was ihr meint. Aber warum ruft er denn nach dieser if-Anweisung:
Code:
if (node.getParentNode() == null)
überhaupt den else Zweig, in dem die von euch genannte if-Anweisung liegt, auf? "Kochen" hat ja keinen Elternknoten, also wird doch folgendes ausgeführt:
Code:
suche(node.getFirstChild(),ausw);
erst dann geht er in den else-Zweig.

Oder hab ich da einen Denkfehler?

EDIT: Also es geht auch einfacher...aber das muss einem ja gesagt werden ;D

Code:
public void suche (String ausw) {
		int i,j;
		
		NodeList nList = doc.getElementsByTagName(ausw); // sucht den entsprechenden Element-Knoten mit dem gewünschtem Namen
		
		for (i = 0; i < nList.getLength(); i++) {
			NodeList nl = nList.item(i).getChildNodes();
			text = ausw+": ";
			for (j = 0; j < nl.getLength(); j++) {
				text += nl.item(j).getNodeName().trim()+" "+nl.item(j).getTextContent().trim();
				System.out.print(text);
				text = "";
			}
		}
}

Allerdings steht hinter jedem Inhalt "#text"!? Was hat das zu sagen, woher kommt das?
Aber eine Erklärung zum oberen Problem, zumindest in bezug auf die if-Anweisung mit der parent-Abfrage wäre trotzdem interessant.

mfg
 
Zuletzt bearbeitet:

Ähnliche Themen

Zurück
Oben