tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
13
ZUGRIFFE
5353
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    stso stso ist offline Mitglied Bronze
    Registriert seit
    Jan 2007
    Beiträge
    41
    Hallo,
    ich hab folgendes Problem. Ich möchte eine XML-Datei parsen. Zum Beispiel diese:

    Code :
    1
    2
    3
    4
    5
    
    <?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 :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
        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?
     

  2. #2
    Avatar von zeja
    zeja zeja ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Sep 2006
    Beiträge
    2.962
    String.trim() entfernt z.B. alle Whitespaces am Anfang und Ende eines Strings.
     

  3. #3
    biturbogolf biturbogolf ist offline Rookie
    Registriert seit
    Apr 2008
    Beiträge
    8
    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?
     

  4. #4
    Avatar von Oliver Gierke
    Oliver Gierke Oliver Gierke ist offline Mitglied Rubin
    Registriert seit
    Dec 2003
    Ort
    Mannheim
    Beiträge
    1.457
    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
     
    In theory, there is no difference between theory and practice. In practice, there is!

    www.olivergierke.de

  5. #5
    biturbogolf biturbogolf ist offline Rookie
    Registriert seit
    Apr 2008
    Beiträge
    8
    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?
     

  6. #6
    Avatar von Oliver Gierke
    Oliver Gierke Oliver Gierke ist offline Mitglied Rubin
    Registriert seit
    Dec 2003
    Ort
    Mannheim
    Beiträge
    1.457
    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!
     
    In theory, there is no difference between theory and practice. In practice, there is!

    www.olivergierke.de

  7. #7
    biturbogolf biturbogolf ist offline Rookie
    Registriert seit
    Apr 2008
    Beiträge
    8
    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.
     

  8. #8
    Avatar von Oliver Gierke
    Oliver Gierke Oliver Gierke ist offline Mitglied Rubin
    Registriert seit
    Dec 2003
    Ort
    Mannheim
    Beiträge
    1.457
    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!
     
    In theory, there is no difference between theory and practice. In practice, there is!

    www.olivergierke.de

  9. #9
    biturbogolf biturbogolf ist offline Rookie
    Registriert seit
    Apr 2008
    Beiträge
    8
    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
     

  10. #10
    stso stso ist offline Mitglied Bronze
    Registriert seit
    Jan 2007
    Beiträge
    41
    Hallo,
    ich hab mir mal JDOM und DOM4J angeschaut. Dort geht das was ich meine so:

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

    JDOM:
    Code :
    1
    2
    3
    
    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.
     

  11. #11
    Avatar von Oliver Gierke
    Oliver Gierke Oliver Gierke ist offline Mitglied Rubin
    Registriert seit
    Dec 2003
    Ort
    Mannheim
    Beiträge
    1.457
    Wie gesagt, das was du als Whitespace ansiehst ist kein Whitespace. Das ist einfach Teil des W3C Java DOM Modells. Whitespace liegt hier vor:
    Code xml:
    1
    2
    3
    4
    5
    6
    
    <code>
      <listing>
        fooobarr
        fooobarr
      </listing>
    </code>
    Zwischen den beiden fooobarr Wörtern besteht whitespace, bzw. davor und danach.

    Gruß
    Ollie
     
    In theory, there is no difference between theory and practice. In practice, there is!

    www.olivergierke.de

  12. #12
    biturbogolf biturbogolf ist offline Rookie
    Registriert seit
    Apr 2008
    Beiträge
    8
    schönen guten morgen

    hab mich damit abgefunden, dass ich die versteckten texte nicht wegbekomme, weil sie einfach da sind...

    [Text entfernt, befindet sich in einem neuen Thema]
    Geändert von zerix (10.04.08 um 09:02 Uhr) Grund: Text gelöscht, weil in einem neuen Thema
     

  13. #13
    stso stso ist offline Mitglied Bronze
    Registriert seit
    Jan 2007
    Beiträge
    41
    Hallo Oliver,
    das die Zeilenumbruche und Tabulatoren innerhalb deines Listing- Elementes mit zu deren Inhalt zählen seh ich auch so. Was mich eben stört das der Parser aus meinem Wurzelelement (wurzel) ein MixedContent- Element macht obwohl es nicht so gemeint ist . Das der Parser nicht eindeutig zuordnen kann was Inhalt und was "gestalterisches" Whitespace ist, seh ich ja auch ein. Auf jeden Fall kann man dasProblem mit den oben genannten "Lösungen" (JDOM,DOM4J) umgehen .
    Vielleicht sollte man sich angewöhne Umbrüche im Content grundsätzlich mit "<br />" wie in HTML zu kennzeichnen. Für Tabulator könnte man "<t />" nehmen .

    Mein Problem war das ich:
    Code :
    1
    2
    3
    4
    5
    
    <?xml version="1.0" encoding="UTF-8"?>
    <wurzel>
        <element>eins</element>
        <element>zwei</element>
    </wurzel>
    geschrieben habe und
    Code :
    1
    
    <?xml version="1.0" encoding="UTF-8"?><wurzel><element>eins</element><element>zwei</element></wurzel>
    gemeint habe.
     

  14. #14
    Avatar von Oliver Gierke
    Oliver Gierke Oliver Gierke ist offline Mitglied Rubin
    Registriert seit
    Dec 2003
    Ort
    Mannheim
    Beiträge
    1.457
    @biturbogolf kannst du bitte für das thema einen neuen thread aufmachen? Wenn wir hier weiter zwei Themen diskutieren wirds unübersichtlich. Und stso war der Initialposter. Schreib mir ne PM, wenn du den neuen Thread angelegt hast, dann entfern ich die Postings hier aus diesem Thread.

    @stso - das ist nicht ganz korrekt. Wie schon oben beschrieben kannst du den Typ Element benutzen und "siehst" dann nicht den vermeintlich leeren Textcontent. Das verhalten der API ist korrekt und auch sinnvoll. Es sind einfach zwei unterschiedlieche Abstraktionsniveaus. Wenn du ein richtiges Mapping von XML auf Objekte willst, dann benutz einen OX Mapper deiner Wahl (Castor, JAXB, XMLBeans) und du musst nicht mit dem Lowlevel API rumspielen.

    Btw. würde dir der DOM Parser für das untere XML ebenfalls nen leeren Textnode für "wurzel" zurückgeben. Das ist nur ne Formatierungsfrage. Deine beiden XML Fragmente sind für einen DOM Parser definitiv das gleiche. Elemente für Formatierungen? Das hatten wir in HTML schon mal. XML ist dazu da Content zu strukturieren, nicht um schöne Umrüche zu machen .

    Gruß
    Ollie
     
    In theory, there is no difference between theory and practice. In practice, there is!

    www.olivergierke.de

Ähnliche Themen

  1. Antworten: 0
    Letzter Beitrag: 10.08.08, 12:26
  2. Antworten: 2
    Letzter Beitrag: 19.05.05, 19:51
  3. Java-Popup ohne "history.go(-1)"
    Von daDom im Forum Javascript & Ajax
    Antworten: 8
    Letzter Beitrag: 11.12.03, 21:56
  4. "fakethumbs" ohne GDlib erstellen?
    Von eLorFiN im Forum PHP
    Antworten: 7
    Letzter Beitrag: 27.08.03, 02:12
  5. Antworten: 4
    Letzter Beitrag: 11.09.02, 16:52