[Java] SAX Denkfehler

martinibook

martinibook

Aktives Mitglied
Thread Starter
Dabei seit
20.08.2005
Beiträge
8.727
Reaktionspunkte
350
[Java] DOM Denkfehler

Hallo,

Irgendwie habe ich ein Problem mit DOM. Ich möchte folgende XML Datei auswerten:

Code:
<privatemessages>
	<folder name="Posteingang">
		<privatemessage>
			<datestamp>2009-08-31 17:38</datestamp>
			<title>AW: Gadget Idee</title>
			<fromuser>abc</fromuser>
			<fromuserid>123</fromuserid>
			<touser>martinibook</touser>
			<message>Nachrichtentext</message>
		</privatemessage>
	</folder>
</privatemessages>

Das ist mein Code:

Code:
try {
	DOMParser parser = new DOMParser();
	InputStream in = new FileInputStream(file);
	InputSource source = new InputSource(in);
	parser.parse(source);
	in.close();

	Document doc = parser.getDocument();


	NodeList listTF1 = doc.getElementsByTagName("privatemessage");
	System.out.println(listTF1.getLength()+" Nachrichten gefunden.");
	for (int i = 0; i < listTF1.getLength(); i++) {
		Node nachrichtNode = listTF1.item(i);
		NodeList list = nachrichtNode.getChildNodes();

		Pn pn = new Pn();

		pn.datum = list.item(0).getNodeValue();
		pn.titel = list.item(1).getNodeValue();
		pn.von = list.item(2).getNodeValue();
		pn.an = list.item(3).getNodeValue();
		pn.nachricht = list.item(4).getNodeValue();

		pn.save(i);
	}
}

Es wird aber rein gar nichts ausgegeben :kopfkratz:

Was mache ich falsch?
 
Zuletzt bearbeitet:
DOM repräsentiert bekannterweise das Dokument als einen Baum. Du musst also über die Knoten bis zu deinem Element dich durchhangeln.

Ach ja: DOM-Parser != SAX-Parser. DOM repräsentiert den Baum, SAX geht sequentiell durch das Dokument. ;)
 
Unterschied zwischen DOM und SAX sollte mir eigentlich klar sein :hum:

Aber Durchhangeln habe ich doch gemacht mit
Code:
doc.getElementsByTagName("privatemessage");
oder? Dann müssten doch die Kinder direkt die Eigenschaften sein, an die ich eigenltich dran wollte. Oder ist da immer noch ein Denkfehler drin?
 
Unterschied zwischen DOM und SAX sollte mir eigentlich klar sein :hum:

Aber Durchhangeln habe ich doch gemacht mit
Code:
doc.getElementsByTagName("privatemessage");
oder? Dann müssten doch die Kinder direkt die Eigenschaften sein, an die ich eigenltich dran wollte. Oder ist da immer noch ein Denkfehler drin?

Ja, du hast noch einen Denkfehler. Wenn dein obiges Code-Snippet dein ganzes Dokument ist, musst du erst

Code:
doc.getElementsByTagName("privatemessage[B]s[/B]");

rufen. An dem Element dir dann alle Folder-Tags geben lassen, von diesen dann privatemessage (ohne s)...

Wie gesagt, das ist ein Baum mit der Wurzel, die bei dir durch doc repräsentiert wird.

Und wenn dir der Unterschied zwischen DOM und SAX klar ist, änder doch bitte den Thread-Titel ;)
 
Thread Titel kann ich nicht ändern, das kann nur ein Mod.

Aber wenn ich nach privatemessage (ohne s) in die Schleife gehe, dann findet der 15 Elemente, wie er dann auch in die Konsole schreibt. Von daher dachte ich eigentlich, ich seie schon am Ziel :kopfkratz:
 
15??? Ist das oben das ganze Dokument???

Jedenfalls kennt der DOM Baum <privatemessage> nicht im Root, <privatemessages> sehr wohl!
 
Man hätte wohl kaum chaotischer in diesem Thread auftreten können …

Das XML Dokument enthält 15 Blöcke mit Privatemessage, und da der "dom" anscheinend 15 kennt, sollte er die auch anschließend verarbeiten können :kopfkratz:
 
Nochmal zur Klärung:

Code:
<privatemessages>
 <folder>
  <privatemessage />*
 </folder>
</privatemessages>

oder

Code:
<privatemessages>
 <folder>
  <privatemessage />
 </folder>*
</privatemessages>

?

Also nur ein folder tag oder pro message ein folder im dokument?
 
Die <privatemessage> stehen all hintereinader:

Code:
<privatemessages>
	<folder name="Posteingang">
		<privatemessage>
			<datestamp>2009-08-30 01:38</datestamp>
			<title>AW: …</title>
			<fromuser>…</fromuser>
			<fromuserid>…</fromuserid>
			<touser>martinibook</touser>
			<message>…</message>
		</privatemessage>
		<privatemessage>
			<datestamp>2009-08-30 19:48</datestamp>
			<title>AW: …</title>
			<fromuser>…</fromuser>
			<fromuserid>…</fromuserid>
			<touser>martinibook</touser>
			<message>…</message>
		</privatemessage>
		<privatemessage>
			<datestamp>2009-08-31 17:38</datestamp>
			<title>AW: …</title>
			<fromuser>…</fromuser>
			<fromuserid>…</fromuserid>
			<touser>martinibook</touser>
			<message>…</message>
		</privatemessage>
	</folder>
</privatemessages>
 
Man hätte wohl kaum chaotischer in diesem Thread auftreten können …

Das XML Dokument enthält 15 Blöcke mit Privatemessage, und da der "dom" anscheinend 15 kennt, sollte er die auch anschließend verarbeiten können :kopfkratz:

was denn nun? du fragst den dom nach privatemessage (ohne s), bekommst einen knoten und der enthält dann 15 kinder???
 
Code:
NodeList listTF1 = doc.getElementsByTagName("privatemessage");
System.out.println(listTF1.getLength()+" Nachrichten gefunden.");

Gibt dann "15 Nachrichten gefunden." aus. Und in der listTF1 sind dann wohl 15 Nodes (= Nachrichten) drin. Dann müsste ich doch wohl die Kinder der jeweiligen Nodes ansprechen können und somit auf Absender, Nachricht, … kommen können. :confused:
 
Ja müsstest du! Es fällt keine Exception? getNodeValue() gibt also einen leeren String oder NULL zurück?

In welchem Encoding ist die Datei abgelegt? Beginnt dein Dokument mit etwas wie

Code:
<?xml version='1.0' encoding='UTF-8'?>

?
 
Zuletzt bearbeitet:
Exakt,
Code:
pn.datum = list.item(1).getNodeValue();
System.out.println(pn.datum);
gibt dann "null" aus. Was bedeutet das?


Code:
<?xml version="1.0" encoding="ISO-8859-1"?>
 
Code:
System.out.println(pn.datum);

bedeutet, dass getNodeValue() null zurückgegeben hat.

Code:
<?xml version="1.0" encoding="ISO-8859-1"?>

gibt an, dass das Dokument in Standard-ISO abgelegt wurde. Du solltest es also auch mit diesem Encoding abgespeichert haben.
 
Gut, warum hat getNodeValue() "null" zurück gegeben? Eigentlich müsste doch da ein Element sein!?

Die Datei ist auch in ISO Latin 1 gepeichert, Smultron zeigt das auch brav an sowie alle Umlaute stimmen.
 
Ist vielleicht ein wenig am Thema vorbei ... aber muss es denn SAX sein, mit JAX - B könntest du dir viel Arbeit sparen.
 
Es ist sowieso gar nicht SAX, sondern ein DOM-Parser, ich hatte mich nur irgendwie gerade verheddert (hatte erst SAX angesetzt und dann dann DOM genommen).
 
Naja auf jeden Fall gehtst du per Hand durch den Baum.

Mit Jax - B setzt du ein paar Annotationen in deiner PN Klasse und fertig :)
 
Naja auf jeden Fall gehtst du per Hand durch den Baum.

Mit Jax - B setzt du ein paar Annotationen in deiner PN Klasse und fertig :)

Er geht ja auch per Hand durch die Liste, anstatt nen Itterator zu nutzen ;) JaxB wäre jedenfalls ne sehr leichte Lösung.
 
Habe lange nicht mehr mit DOM hantiert... Aber Du übersiehst tatsächlich was:
Text (auch ein Whitespace) ist ebenfalls ein (Unter-)Knoten.

Daraus folgt:
1. Jedes Deiner <privatemessage> hat 13 Kinder. Die Elemente und die Tabs/Zeilenvorschübe.
Mit item(index) darf man an der Stelle nicht hantieren, zumal Du ohnehin ab "pn.an=" die falschen Werte übernehmen würdest... ;)

2. Auch wenn Du über item(index) an das richtige Element gekommen bist, gibt dir getNodeValue immer null aus. Ist bei Element-Knoten immer null, siehe: http://java.sun.com/j2se/1.4.2/docs/api/org/w3c/dom/Node.html.
Du musst Dir erst den Textknoten darunter (s.o.) holen.
z.B. mit getFirstChild:
Code:
pn.datum = list.item(0).getFirstChild().getNodeValue()

Ich kann Dir JAXB ebenfalls wärmstens empfehlen.

Gruß,
Björn
 
Zurück
Oben Unten