Java XML Datei parsen und DOM Struktur erstellen ohne "unnötige" Whitespaces

stso

Mitglied
Hallo,
ich hab folgendes Problem. Ich möchte eine XML-Datei parsen. Zum Beispiel diese:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<wurzel>
	<element>eins</element>
	<element>zwei</element>
</wurzel>

Und daraus eine DOM-Struktur (org.w3c.dom) erstellen.
Mein Problem sind nun die "überflüssigen" Whitespaces im Dokument (\n,\t, usw...). Wenn ich das DOM- Dokument einmal in einem "preorder"-Durchlauf durchlaufe sieht eine mögliche Ausgabe so aus:

#document
wurzel
#text <- unerwünschte Whitespaces
element
#text{eins}
#text <- unerwünschte Whitespaces
element
#text{zwei}
#text <- unerwünschte Whitespaces

gewünscht ist aber diese:

#document
wurzel
element
#text{eins}
element
#text{zwei}

Deshalb hab ich mir gedacht das ich einfach alle Textelemente die nur Whitespaces enthalten lösche. Und habe mir folgende Methode geschrieben:

Code:
	public static void removeWhiteSpaces(Node node)
	{
		System.out.println(node.getNodeName());
		if(node.hasChildNodes())
		{
			NodeList childs = node.getChildNodes();
			for(int i=0;i<childs.getLength();i++)
			{
				Node child = childs.item(i);
				if (child.getNodeType() == Node.TEXT_NODE
						&& child.getNodeValue().matches("^\\s*$")
						&& child.getParentNode() != null)
				{
					child.getParentNode().removeChild(child);
				}
				else
				{
					removeWhiteSpaces(child);
				}
			}
		}
	}

Doch leider funktioniert diese Methode nicht. Nachdem ich den ersten #test{whitespace} Knoten gelöscht habe wird mir bei weiteren Schleifendurchläufen der Schleife über die Kinder das #test- Objekt über item(i) zurückgegeben, das ich eigetlich gelöscht habe. Wo ist mein Denkfehler?

Kann man die Whitespaces irgendwie anders entfernen. Auf die Funktion factory.setIgnorableElementContentWhitespace(false); kann ich nicht zurückgreifen da diese wohl immer eine DTD oder ein XML-Schema benötigt?! Manchmal stehen diese bei meinen Anwendungsfällen nicht zur Verfügung.

Könnte man evtl. die Datei als String einlesen und alle Whitespaces(bzw. alle die alleinig zwischen ">" und "<" stehen ) entfernen?

Der XML-Input wird später relativ umfangreich -bis zu 100000 Elemente. Wie könnte man das die Whitespaces bzw. die Whitespace- Text- Elemente effektiv entfernen?
 
Hallo

habe ein ähnliches Probelm mit den Whitespaces...

Wollte das mit DTD lösen, aber irgendwie stehe ich auf dem Schlauch und finde nicht die richtige Lösung. Wie macht man das genau mit DTD oder Schemas?
 
Grundsätzliche Frage: warum stört der "Whitespace" (eigentlich ist das kein Whitespace)? Beim Arbeiten mit XML ohne XSD ist das immer so eine Sache. Soweit ich weiß hat jeder Node IMMER einen Childnode vom Typ textnode, wenn das element nicht eins ist, dass sofort geschlossen wird (<foo /> - kein Textnode, <foo></foo> - immer ein Textnode).

Grundsätzlich ist es immer sinnvoller mit "Element" als Typ zu arbeiten, da dies Teile des XMl Dokuementes auf dem Abstratktionslevel abstrahiert, in dem du wahrscheinlich denkst. Node hingegen unterteilt das XML Dokument wesentlich feingranularer und ist quasi die kleinste Einheit. Attribute eines Elements sind auch Nodes! D.h. man kann sagen, dass das, was man sich landläufig unter einem XML Element vorstellt durch Elemtent abstrahiert wird und wiederum aus vielen Nodes besteht (Nodes die Attribute speichern, einen Node für den Text usw).

Daher macht es wie gesagt für Standard XML Operationen meist mehr Sinn, mit Element zu arbeiten. Dann kann man mit getElementByTagName("element") alle Elemente mit dem Namen "element" bekommen.

Gruß
Ollie
 
Also jedes Element oder vielelicht sogar Node hat ein versteckten Text als Kind, der leer ist. Habe ich das richtig verstanden?

Bekomme ich die irgendwie weg?
 
Naja, ein Element (was halt auch vom Typ Node ist) hat halt immer einen Childnode vom Type textnode insofern es ein Offenes Element ist (sowas wie <foo></foo>). D.h. Childnode != Unterelemente. Das ist wichtig zu verstehen. Wenn du dir im JavaDoc mal Node und Element anschaust, wird das auch anhand der Methoden bzw. der Doku an sich recht schnell deutlich.

Warum willst du die wegbekommen? Ich seh den Anwendungsfall nicht (mal abgesehen davon, dass es wohl nicht geht ;) )

REINHAUN!
 
Der Anwendungsfall...

in erster Linie geht es darum mich mit XML etc. auseinander zu setzen.

Im Anschluss soll ich einen Parser in C++ schreiben, der einen DOMTREE erstellt. Desweiteren soll ich ahlt auch Sonderformen abklopfen, was geht, was nicht geht etc.
 
Ja moment, wenn du einen Parser schreiben sollst, dann entscheidest DU ja über das Objektmodell. Dann würde ich sagen, W3C Spec schnappen und los.

Btw. hast du was besonderes Verbrochen oder soll das was in Richtung "lehrreich" sein? XML Parser gibt es (auch in C++) wie Sand am Meer ;)

REINHAUN!
 
Ich mache gerade meinen Bachelor und das wird meine Abschlussarbeit. Ist so, dass ich das für emien Firma machen muss, weil aus Sicherheitsgründen ein anderer Parser nicht verwendet werden darf...

ich hab auch noch nciht den ansatz, wie ich ds machen soll...

mein betreuer ist auch nicht gerade begeistert, weil er eigentlich mit xerces super zurecht kommt.

mal schauen
 
Hallo,
ich hab mir mal JDOM und DOM4J angeschaut. Dort geht das was ich meine so:

DOM4J:
Code:
SAXReader saxParser = new SAXReader();
saxParser.setMergeAdjacentText(true);
saxParser.setStripWhitespaceText(true);
Document dom4jDoc = saxParser.read("xml.xml");

JDOM:
Code:
SAXBuilder saxParser = new SAXBuilder();
saxParser.setIgnoringBoundaryWhitespace(true);
Document jDOMdoc = saxParser.build("xml.xml");

doch beim den Java- Standard-Parsern kann man das Entfernen der Whitespaces wohl nicht realsiieren?!
@Oliver: In meinem Fall wäre das Trennen der Elementes von dessen Textinhalt eigentlich sinnvoll. Ich muss so eine Art XML-Diff schreiben und da ist die Trennung von Vorteil. Ich werde mir aber überlegen ob ich nicht auf dom4j umsteige, da es da auch noch jede Menge zusätzliche nützliche Funktionen zu geben scheint.
 
Zurück