Normalisierung beim DOM-Parsing mit Java – wie funktioniert das?

Lesezeit: 5 Minuten

Normalisierung beim DOM Parsing mit Java wie funktioniert das
Apfelmühle

Ich habe die folgende Zeile im Code für einen DOM-Parser unter gesehen dieses Tutorial.

doc.getDocumentElement().normalize();

Warum führen wir diese Normalisierung durch?
Ich lese das Dokumente aber ich verstand kein Wort.

Platziert alle Textknoten in der vollen Tiefe des Teilbaums unterhalb dieses Knotens

Okay, kann mir dann jemand (am besten mit einem Bild) zeigen, wie dieser Baum aussieht?

Kann mir jemand erklären, warum eine Normalisierung erforderlich ist?
Was passiert, wenn wir uns nicht normalisieren?

  • Unabhängig von Ihrer Frage lesen Sie bitte den Hinweis zum Beispiel: “Der DOM-Parser ist langsam und verbraucht viel Speicher, wenn er ein XML-Dokument lädt, das viele Daten enthält. Bitte ziehen Sie den SAX-Parser als Lösung in Betracht, SAX ist schneller als DOM und verbraucht weniger Speicher.”.

    – wulfgarpro

    9. Dezember 2012 um 10:27 Uhr

  • @wulfgar.pro – Ich verstehe, was du gesagt hast. Aber ich möchte die Dinge verstehen, die ich in der Frage gestellt habe. Ich werde auch bald SAX-Parsing machen.

    – Apfelmühle

    9. Dezember 2012 um 11:01 Uhr

  • Die Suche bei Google nach “xml normalisieren” ergab einige Ergebnisse, die nützlich erscheinen. Es sieht so aus, als wäre es der Normalisierung in Datenbanken ähnlich.

    – Apfelmühle

    9. Dezember 2012 um 11:37 Uhr

  • @EJP – ähm … es ist immer noch nicht klar, weil ich XML nicht im Detail kenne und nur ein paar einführende Seiten darüber gelesen habe. Übrigens, verstehen Sie mich nicht falsch, Sie haben genau das getan, was der Autor des Dokuments getan hat – indem Sie komplexe Wörter anstelle von einfachem Englisch verwenden (einfach wie ein Hechtstab = leicht zu verstehen). Einfache Wörter zuerst und Jargon funktionieren später besser für mich.

    – Apfelmühle

    9. Dezember 2012 um 12:03 Uhr


  • Zum jetzigen Zeitpunkt verweist die referenzierte Website auf diesen SO-Beitrag. Mein Gehirn hat gerade einen Abhängigkeitsfehler ausgegeben.

    – Schachnerd

    25. Juli 2013 um 21:22 Uhr

Normalisierung beim DOM Parsing mit Java wie funktioniert das
JB Niet

Der Rest des Satzes lautet:

wobei nur Struktur (z. B. Elemente, Kommentare, Verarbeitungsanweisungen, CDATA-Abschnitte und Entitätsreferenzen) Textknoten trennt, dh es gibt weder benachbarte Textknoten noch leere Textknoten.

Dies bedeutet im Wesentlichen, dass das folgende XML-Element

<foo>hello 
wor
ld</foo>

könnte so in einem denormalisierten Knoten dargestellt werden:

Element foo
    Text node: ""
    Text node: "Hello "
    Text node: "wor"
    Text node: "ld"

Nach der Normalisierung sieht der Knoten so aus

Element foo
    Text node: "Hello world"

Und dasselbe gilt für Attribute: <foo bar="Hello world"/>Kommentare usw.

  • Aha! jetzt ist es viel klarer. Ich weiß nichts über Datenstrukturen (???) und Knoten. Aber ich habe mir die Baumstruktur kurz angesehen und vermute, dass ein Computer “Hallo Welt” so speichern könnte, wie Sie es vorgeschlagen haben. Ist das richtig ?

    – Apfelmühle

    9. Dezember 2012 um 13:12 Uhr

  • Sie müssen die Grundlagen von DOM lernen. Ja, DOM repräsentiert ein XML-Dokument als Baum. Und in einem Baum haben Sie einen Wurzelknoten mit Kindknoten, jeder Kindknoten hat auch Kindknoten usw. Das ist ein Baum. Element ist eine Art Knoten und TextNode ist eine andere Art von Knoten.

    – JB Nizet

    9. Dezember 2012 um 13:20 Uhr

  • Danke JB Nizet. Ich kann Ihnen gar nicht sagen, wie erleichtert ich bin, nachdem ich eine Richtung bekommen habe.

    – Apfelmühle

    9. Dezember 2012 um 13:26 Uhr

  • @ user2043553, die Zeilenumbrüche sind eigentlich der Punkt dort. Ohne Zeilenumbrüche würden Sie den Unterschied nicht sehen. Falls Sie es nicht verstanden haben sollten: Die Normalisierung „korrigiert“ das XML, sodass ein Tag als ein Element interpretiert wird. Wenn Sie das nicht getan haben, kann es passieren, dass genau diese Zeilenumbrüche als Trennzeichen zwischen mehreren Elementen des gleichen Typs (bzw. im gleichen Tag) interpretiert werden.

    – Stapelbar

    23. Oktober 2014 um 15:59 Uhr


  • @Stacky, im Beispiel gibt es zwei neue Zeilen, sie werden nach der Normalisierung im Beispiel nicht angezeigt, was die Leute glauben lassen könnte, dass sie nicht mehr vorhanden sind. Der resultierende Textknoten mit angezeigten Zeilenumbrüchen würde wie folgt aussehen: “Hello\nwor\nld” Normalisieren entfernt keine Zeilenumbrüche.

    – Christian

    22. März 2015 um 19:09 Uhr

Normalisierung beim DOM Parsing mit Java wie funktioniert das
AVA

Einfach gesagt ist Normalisierung die Reduzierung von Redundanzen.
Beispiele für Redundanzen:

a) Leerzeichen außerhalb der Root-/Dokument-Tags ()
b) Leerzeichen innerhalb des Start-Tags (<>) und End-Tag (…>)
c) Leerzeichen zwischen Attributen und ihren Werten (d. h. Leerzeichen zwischen Schlüsselname und =”)
d) überflüssige Namespace-Deklarationen
e) Zeilenumbrüche/Leerzeichen in Texten von Attributen und Tags
f) Kommentare etc…

Als Erweiterung der Antwort von @JBNizet für technisch versiertere Benutzer ist hier die Implementierung von org.w3c.dom.Node Schnittstelle ein com.sun.org.apache.xerces.internal.dom.ParentNode aussieht, gibt Ihnen eine Vorstellung davon, wie es tatsächlich funktioniert.

public void normalize() {
    // No need to normalize if already normalized.
    if (isNormalized()) {
        return;
    }
    if (needsSyncChildren()) {
        synchronizeChildren();
    }
    ChildNode kid;
    for (kid = firstChild; kid != null; kid = kid.nextSibling) {
         kid.normalize();
    }
    isNormalized(true);
}

Es durchläuft alle Knoten rekursiv und ruft auf kid.normalize()

Dieser Mechanismus wird in außer Kraft gesetzt org.apache.xerces.dom.ElementImpl

public void normalize() {
     // No need to normalize if already normalized.
     if (isNormalized()) {
         return;
     }
     if (needsSyncChildren()) {
         synchronizeChildren();
     }
     ChildNode kid, next;
     for (kid = firstChild; kid != null; kid = next) {
         next = kid.nextSibling;

         // If kid is a text node, we need to check for one of two
         // conditions:
         //   1) There is an adjacent text node
         //   2) There is no adjacent text node, but kid is
         //      an empty text node.
         if ( kid.getNodeType() == Node.TEXT_NODE )
         {
             // If an adjacent text node, merge it with kid
             if ( next!=null && next.getNodeType() == Node.TEXT_NODE )
             {
                 ((Text)kid).appendData(next.getNodeValue());
                 removeChild( next );
                 next = kid; // Don't advance; there might be another.
             }
             else
             {
                 // If kid is empty, remove it
                 if ( kid.getNodeValue() == null || kid.getNodeValue().length() == 0 ) {
                     removeChild( kid );
                 }
             }
         }

         // Otherwise it might be an Element, which is handled recursively
         else if (kid.getNodeType() == Node.ELEMENT_NODE) {
             kid.normalize();
         }
     }

     // We must also normalize all of the attributes
     if ( attributes!=null )
     {
         for( int i=0; i<attributes.getLength(); ++i )
         {
             Node attr = attributes.item(i);
             attr.normalize();
         }
     }

    // changed() will have occurred when the removeChild() was done,
    // so does not have to be reissued.

     isNormalized(true);
 } 

Ich hoffe, das spart Ihnen etwas Zeit.

924450cookie-checkNormalisierung beim DOM-Parsing mit Java – wie funktioniert das?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy