Was ist der Unterschied zwischen SAX und DOM?


242

Ich habe einige Artikel über XML gelesen Parser auf SAX und DOM gestoßen .

SAXOPHON ist ereignisbasiert und DOM ist ein Baummodell - ich verstehe die Unterschiede zwischen diesen Konzepten nicht.

Nach meinem Verständnis bedeutet ereignisbasiert, dass dem Knoten eine Art Ereignis passiert. Wenn Sie beispielsweise auf einen bestimmten Knoten klicken, werden alle Unterknoten angezeigt, anstatt alle Knoten gleichzeitig zu laden. Beim DOM- Parsing werden jedoch alle Knoten geladen und das Baummodell erstellt.

Ist mein Verständnis richtig?

Bitte korrigieren Sie mich Wenn ich falsch liege oder mir das ereignisbasierte und Baummodell auf einfachere Weise erkläre.


Eigentlich ist ein DOM kein Parser. Jede gegebene DOM-basierte Software kann Markup-Parsing enthalten oder nicht, und die meisten HTML-DOM-Programme tun dies. Ein DOM ist jedoch eine völlig separate Sache, die möglicherweise überhaupt keinem Serialisierungsformat zugeordnet ist.
Bob77

Antworten:


305

Nun, du bist nah dran.

In SAX werden Ereignisse ausgelöst, wenn das XML analysiert wird . Wenn der Parser das XML analysiert und auf ein beginnendes Tag stößt (z. B. <something>), wird das tagStartedEreignis ausgelöst (der tatsächliche Name des Ereignisses kann abweichen). Wenn das Ende des Tags beim Parsen ( </something>) erreicht wird, wird es ebenfalls ausgelöst tagEnded. Die Verwendung eines SAX-Parsers bedeutet, dass Sie diese Ereignisse behandeln und die mit jedem Ereignis zurückgegebenen Daten verstehen müssen.

In DOM werden beim Parsen keine Ereignisse ausgelöst. Das gesamte XML wird analysiert und ein DOM-Baum (der Knoten im XML) wird generiert und zurückgegeben. Nach dem Analysieren kann der Benutzer im Baum navigieren, um auf die verschiedenen Daten zuzugreifen, die zuvor in die verschiedenen Knoten im XML eingebettet waren.

Im Allgemeinen ist DOM einfacher zu verwenden, muss jedoch das gesamte XML analysieren, bevor Sie es verwenden können.


135
+1 - zur Verdeutlichung: Verwenden Sie einen DOM-Parser mit kleineren Dateien, die in den Arbeitsspeicher passen. Verwenden Sie einen SAX-Parser für große Dateien, die dies nicht tun.
Richard H

danke @spartkymat. Aber im Falle eines SAX-Ereignisses kann der SAX-Parser wissen, dass ein bestimmter untergeordneter Knoten ein Kind eines bestimmten übergeordneten Knotens ist? Oder wird es einfach analysiert? beispielsweise. Ich habe eine <Unternehmen> und Kind ist <Mitarbeiter>. In diesem Fall werden das Unternehmen und der Mitarbeiter nur analysiert oder wird die Beziehung angezeigt, in der das Unternehmen Eltern des Mitarbeiters ist?
user414967

4
Es wird nur analysiert. Sie müssen diese Informationen selbst pflegen (über eine Zustandsmaschine oder auf andere Weise). Umso mehr Grund, einen DOM-Parser zu verwenden (sofern die Ressourcen dies zulassen) :-).
Sparkymat

1
@Richard H Ich würde argumentieren, dass jeder, der XML-Dateien verwendet, die so groß sind, dass sie nicht in den Arbeitsspeicher passen, etwas sehr sehr Falsches tut.
antred

1
Laden Sie ein Excel mit einer Größe von 40 m, verwenden Sie 200 m Speicher, wenn Sie einen SAX-Parser verwenden, aber 9 g Speicher, wenn Sie einen DOM-Parser verwenden.
zhiyuan_

98

In wenigen Worten ...

SAX ( S imple A PI für X ML): ist ein Strom-Prozessor. Sie haben zu jeder Zeit nur einen winzigen Teil im Speicher und "schnüffeln" den XML-Stream, indem Sie Rückrufcode für Ereignisse wie implementierentagStarted() usw. . Er verwendet fast keinen Speicher, aber Sie können keine "DOM" -Dinge wie xpath oder traverse ausführen Bäume.

DOM ( D ocument O bject M odel): Sie laden das Ganze in den Speicher - es ist ein gewaltiger Speicherfresser. Sie können Speicher auch mit mittelgroßen Dokumenten sprengen. Sie können aber xpath verwenden und den Baum usw. durchqueren.


66

Hier in einfacheren Worten:

DOM

  • Baummodell-Parser (objektbasiert) (Knotenbaum).

  • DOM lädt die Datei in den Speicher und analysiert sie dann.

  • Hat Speicherbeschränkungen, da die gesamte XML-Datei vor dem Parsen geladen wird.

  • DOM wird gelesen und geschrieben (kann Knoten einfügen oder löschen).

  • Wenn der XML-Inhalt klein ist, bevorzugen Sie den DOM-Parser.

  • Die Suche vorwärts und rückwärts ist möglich, um die Tags zu durchsuchen und die Informationen in den Tags auszuwerten. Dies erleichtert die Navigation.

  • Langsamer zur Laufzeit.

SAXOPHON

  • Ereignisbasierter Parser (Sequenz von Ereignissen).

  • SAX analysiert die Datei beim Lesen, dh Knoten für Knoten.

  • Keine Speicherbeschränkungen, da der XML-Inhalt nicht im Speicher gespeichert wird.

  • SAX ist schreibgeschützt, dh der Knoten kann nicht eingefügt oder gelöscht werden.

  • Verwenden Sie den SAX-Parser, wenn der Speicherinhalt groß ist.

  • SAX liest die XML-Datei von oben nach unten und eine Rückwärtsnavigation ist nicht möglich.

  • Schneller zur Laufzeit.


perfekt ... erwartete eine Antwort in Punkten. Gute Arbeit :)
Kunal Gupta

37

Sie verstehen das DOM-basierte Modell richtig. Die XML-Datei wird als Ganzes geladen und ihr gesamter Inhalt wird als speicherinterne Darstellung des Baums erstellt, den das Dokument darstellt. Dies kann je nach Größe der Eingabedatei zeit- und speicherintensiv sein. Der Vorteil dieses Ansatzes besteht darin, dass Sie problemlos jeden Teil des Dokuments abfragen und alle Knoten in der Baumstruktur frei bearbeiten können.

Der DOM-Ansatz wird normalerweise für kleine XML-Strukturen verwendet (wobei klein davon abhängt, wie viel Leistung und Speicher Ihre Plattform hat), die nach dem Laden möglicherweise auf unterschiedliche Weise geändert und abgefragt werden müssen.

SAX hingegen ist für die Verarbeitung von XML-Eingaben praktisch jeder Größe ausgelegt. Anstatt dass das XML-Framework die harte Arbeit für Sie erledigt, um die Struktur des Dokuments herauszufinden und potenziell viele Objekte für alle Knoten, Attribute usw. vorzubereiten, überlässt SAX dies vollständig Ihnen.

Grundsätzlich wird die Eingabe von oben gelesen und die von Ihnen bereitgestellten Rückrufmethoden aufgerufen, wenn bestimmte "Ereignisse" auftreten. Ein Ereignis trifft möglicherweise auf ein öffnendes Tag, ein Attribut im Tag, findet Text in einem Element oder stößt auf ein End-Tag.

SAX liest hartnäckig die Eingabe und sagt Ihnen, was es auf diese Weise sieht. Es liegt an Ihnen, alle Statusinformationen zu pflegen, die Sie benötigen. Normalerweise bedeutet dies, dass Sie eine Art Zustandsmaschine aufbauen.

Dieser Ansatz für die XML-Verarbeitung ist zwar viel langwieriger, kann aber auch sehr leistungsfähig sein. Stellen Sie sich vor, Sie möchten nur die Titel von Nachrichtenartikeln aus einem Blog-Feed extrahieren. Wenn Sie dieses XML mit DOM lesen, werden alle Artikelinhalte, alle Bilder usw., die im XML enthalten sind, in den Speicher geladen, auch wenn Sie nicht einmal daran interessiert sind.

Mit SAX können Sie einfach überprüfen, ob der Elementname (z. B.) "title" ist, wenn Ihre Ereignismethode "startTag" aufgerufen wird. Wenn ja, wissen Sie, dass Sie hinzufügen müssen, was auch immer das nächste "elementText" -Ereignis Ihnen bietet. Wenn Sie den Ereignisaufruf "endTag" erhalten, prüfen Sie erneut, ob dies das abschließende Element des "Titels" ist. Danach ignorieren Sie einfach alle weiteren Elemente, bis entweder die Eingabe endet oder ein anderes "startTag" mit dem Namen "title" erscheint. Und so weiter...

Auf diese Weise können Sie Megabyte und Megabyte XML durchlesen und nur die winzige Datenmenge extrahieren, die Sie benötigen.

Die negative Seite dieses Ansatzes ist natürlich, dass Sie viel mehr Bücher führen müssen, je nachdem, welche Daten Sie extrahieren müssen und wie kompliziert die XML-Struktur ist. Darüber hinaus können Sie die Struktur des XML-Baums natürlich nicht ändern, da Sie ihn nie als Ganzes zur Hand haben.

Im Allgemeinen eignet sich SAX daher zum Durchsuchen potenziell großer Datenmengen, die Sie mit Blick auf eine bestimmte "Abfrage" erhalten, die jedoch nicht geändert werden müssen, während DOM eher darauf abzielt, Ihnen auf Kosten die volle Flexibilität bei der Änderung von Struktur und Inhalt zu bieten der höheren Ressourcennachfrage.


16

Sie vergleichen Äpfel und Birnen. SAX ist ein Parser , der serialisierte DOM-Strukturen analysiert. Es gibt viele verschiedene Parser, und "ereignisbasiert" bezieht sich auf die Parsing-Methode.

Vielleicht ist eine kleine Zusammenfassung angebracht:

  • Das Dokumentobjektmodell (DOM) ist ein abstraktes Datenmodell, das eine hierarchische, baumbasierte Dokumentstruktur beschreibt. Ein Dokumentbaum besteht aus Knoten , nämlich Element-, Attribut- und Textknoten (und einigen anderen). Knoten haben Eltern, Geschwister und Kinder und können usw. durchlaufen werden, all das, was Sie von JavaScript gewohnt sind (was übrigens nichts mit dem DOM zu tun hat).

  • Eine DOM-Struktur kann serialisiert , dh unter Verwendung einer Auszeichnungssprache wie HTML oder XML in eine Datei geschrieben werden. Eine HTML- oder XML-Datei enthält somit eine "ausgeschriebene" oder "abgeflachte" Version eines abstrakten Dokumentbaums.

  • Damit ein Computer einen DOM-Baum aus einer Datei bearbeiten oder sogar anzeigen kann, muss er die Datei deserialisieren oder analysieren und den abstrakten Baum im Speicher rekonstruieren. Hier kommt das Parsen ins Spiel.

Nun kommen wir zur Natur der Parser. Eine Möglichkeit zum Parsen besteht darin, das gesamte Dokument einzulesen, eine Baumstruktur im Speicher rekursiv aufzubauen und schließlich das gesamte Ergebnis dem Benutzer zur Verfügung zu stellen. (Ich nehme an, Sie könnten diese Parser "DOM-Parser" nennen.) Das wäre sehr praktisch für den Benutzer (ich denke, das macht der XML-Parser von PHP), aber er leidet unter Skalierbarkeitsproblemen und wird für große Dokumente sehr teuer.

Auf der anderen Seite betrachtet die ereignisbasierte Analyse, wie sie von SAX durchgeführt wird, die Datei linear und ruft den Benutzer einfach zurück , wenn er auf ein strukturelles Datenelement stößt, wie "Dieses Element gestartet", "Dieses Element beendet". , "etwas Text hier" usw. Dies hat den Vorteil, dass es ohne Rücksicht auf die Größe der Eingabedatei für immer weitergehen kann, aber es ist viel niedriger, da der Benutzer die gesamte eigentliche Verarbeitungsarbeit erledigen muss (durch Bereitstellung) Rückrufe). Um zu Ihrer ursprünglichen Frage zurückzukehren, bezieht sich der Begriff "ereignisbasiert" auf die Analyseereignisse , die der Parser beim Durchlaufen der XML-Datei auslöst.

Der Wikipedia-Artikel enthält viele Details zu den Phasen der SAX-Analyse.


11

Ich werde eine allgemeine Q & A-orientierte Antwort auf diese Frage geben:

Antwort auf Fragen

Warum brauchen wir XML-Parser?

Wir brauchen XML-Parser, weil wir nicht alles in unserer Anwendung von Grund auf neu machen wollen, und wir brauchen einige "Hilfsprogramme" oder Bibliotheken, um etwas sehr Niedriges, aber für uns sehr Notwendiges zu tun. Zu diesen einfachen, aber notwendigen Dingen gehören das Überprüfen der Form, das Überprüfen des Dokuments anhand seiner DTD oder seines Schemas (nur zum Überprüfen von Parsern), das Auflösen von Zeichenreferenzen, das Verstehen von CDATA-Abschnitten usw. XML-Parser sind solche "Hilfsprogramme" und erledigen all diese Aufgaben. Mit dem XML-Parser sind wir vor vielen dieser Komplexitäten geschützt und können uns darauf konzentrieren, durch die von den Parsern implementierten APIs nur auf hoher Ebene zu programmieren und so die Programmiereffizienz zu steigern.

Welches ist besser, SAX oder DOM?

Sowohl der SAX- als auch der DOM-Parser haben ihre Vor- und Nachteile. Welches besser ist, sollte von den Eigenschaften Ihrer Anwendung abhängen (siehe einige Fragen unten).

Welcher Parser kann bessere Geschwindigkeits-, DOM- oder SAX-Parser erhalten?

SAX-Parser kann eine bessere Geschwindigkeit erreichen.

Was ist der Unterschied zwischen einer baumbasierten API und einer ereignisbasierten API?

Eine baumbasierte API ist um eine Baumstruktur zentriert und bietet daher Schnittstellen zu Komponenten eines Baums (bei denen es sich um ein DOM-Dokument handelt) wie Dokumentschnittstelle, Knotenschnittstelle, NodeList-Schnittstelle, Elementschnittstelle, Attr-Schnittstelle usw. Im Gegensatz dazu bietet eine ereignisbasierte API jedoch Schnittstellen für Handler. Es gibt vier Handler-Schnittstellen, die ContentHandler-Schnittstelle, die DTDHandler-Schnittstelle, die EntityResolver-Schnittstelle und die ErrorHandler-Schnittstelle.

Was ist der Unterschied zwischen einem DOM-Parser und einem SAX-Parser?

DOM-Parser und SAX-Parser funktionieren auf unterschiedliche Weise:

  • Ein DOM-Parser erstellt aus dem Eingabedokument eine Baumstruktur im Speicher und wartet dann auf Anforderungen vom Client. Ein SAX-Parser erstellt jedoch keine interne Struktur. Stattdessen werden die Vorkommen von Komponenten eines Eingabedokuments als Ereignisse verwendet und dem Client mitgeteilt, was beim Lesen des Eingabedokuments gelesen wird. EIN

  • Der DOM-Parser bedient die Clientanwendung immer mit dem gesamten Dokument, unabhängig davon, wie viel der Client tatsächlich benötigt. Ein SAX-Parser bedient die Client-Anwendung jedoch immer nur mit Teilen des Dokuments zu einem bestimmten Zeitpunkt.

  • Beim DOM-Parser müssen Methodenaufrufe in der Clientanwendung explizit sein und eine Art Kette bilden. Bei SAX werden jedoch einige bestimmte Methoden (normalerweise vom Cient überschrieben) automatisch (implizit) auf eine Weise aufgerufen, die als "Rückruf" bezeichnet wird, wenn bestimmte Ereignisse auftreten. Diese Methoden müssen vom Client nicht explizit aufgerufen werden, obwohl wir sie explizit aufrufen könnten.

Wie entscheiden wir, welcher Parser gut ist?

Idealerweise sollte ein guter Parser schnell (zeiteffizient), platzsparend, funktionsreich und einfach zu bedienen sein. In Wirklichkeit verfügt jedoch keiner der Hauptparser über alle diese Funktionen gleichzeitig. Ein DOM-Parser ist beispielsweise reich an Funktionen (da er einen DOM-Baum im Speicher erstellt und es Ihnen ermöglicht, wiederholt auf einen beliebigen Teil des Dokuments zuzugreifen und den DOM-Baum zu ändern), ist jedoch platzsparend, wenn das Dokument sehr groß ist und es dauert ein bisschen lange, um zu lernen, wie man damit arbeitet. Ein SAX-Parser ist jedoch bei großen Eingabedokumenten viel platzsparender (da er keine interne Struktur erstellt). Darüber hinaus läuft es schneller und ist leichter zu erlernen als DOM Parser, da seine API sehr einfach ist. Aber aus Sicht der Funktionalität, Es bietet weniger Funktionen, was bedeutet, dass sich die Benutzer selbst um mehr kümmern müssen, z. B. um die Erstellung eigener Datenstrukturen. Was ist übrigens ein guter Parser? Ich denke, die Antwort hängt wirklich von den Eigenschaften Ihrer Bewerbung ab.

In welchen realen Anwendungen ist die Verwendung des SAX-Parsers vorteilhafter als die Verwendung des DOM-Parsers und umgekehrt? Was ist die übliche Anwendung für einen DOM-Parser und für einen SAX-Parser?

In den folgenden Fällen ist die Verwendung des SAX-Parsers vorteilhafter als die Verwendung des DOM-Parsers.

  • Das Eingabedokument ist zu groß für den verfügbaren Speicher (in diesem Fall ist SAX Ihre einzige Wahl).
  • Sie können das Dokument in kleinen zusammenhängenden Eingabestücken verarbeiten. Sie benötigen nicht das gesamte Dokument, bevor Sie nützliche Arbeit leisten können
  • Sie möchten nur den Parser verwenden, um die gewünschten Informationen zu extrahieren, und Ihre gesamte Berechnung basiert vollständig auf den von Ihnen selbst erstellten Datenstrukturen. Tatsächlich erstellen wir in den meisten unserer Anwendungen eigene Datenstrukturen, die normalerweise nicht so kompliziert sind wie der DOM-Baum. In diesem Sinne ist die Wahrscheinlichkeit, einen DOM-Parser zu verwenden, geringer als die eines SAX-Parsers.

In den folgenden Fällen ist die Verwendung des DOM-Parsers vorteilhafter als die Verwendung des SAX-Parsers.

  • Ihre Anwendung muss gleichzeitig auf weitgehend separate Teile des Dokuments zugreifen können.
  • Ihre Anwendung verwendet möglicherweise eine interne Datenstruktur, die fast so kompliziert ist wie das Dokument selbst.
  • Ihre Anwendung muss das Dokument wiederholt ändern.
  • Ihre Anwendung muss das Dokument über viele Methodenaufrufe für einen erheblichen Zeitraum speichern.

Beispiel (Verwenden Sie einen DOM-Parser oder einen SAX-Parser?):

Angenommen, ein Ausbilder verfügt über ein XML-Dokument, das alle persönlichen Informationen der Schüler sowie die Punkte enthält, die seine Schüler in seiner Klasse gemacht haben, und weist den Schülern jetzt mithilfe einer Anwendung die Abschlussnoten zu. Was er produzieren will, ist eine Liste mit der SSN und den Noten. Wir gehen auch davon aus, dass der Ausbilder in seiner Bewerbung keine Datenstruktur wie Arrays verwendet, um die persönlichen Informationen des Schülers und die Punkte zu speichern. Wenn der Ausbilder beschließt, denjenigen, die den Klassendurchschnitt oder höher erreicht haben, A zu geben und den anderen B zu geben, sollte er in seiner Anwendung einen DOM-Parser verwenden. Der Grund ist, dass er nicht wissen kann, wie hoch der Klassendurchschnitt ist, bevor das gesamte Dokument verarbeitet wird. Was er wahrscheinlich in seiner Bewerbung tun muss, ist zuerst alle Studenten durchzusehen Punkte und berechnen Sie den Durchschnitt. Sehen Sie sich dann das Dokument erneut an und weisen Sie jedem Schüler die Abschlussnote zu, indem Sie die Punkte, die er verdient hat, mit dem Klassendurchschnitt vergleichen. Wenn der Ausbilder jedoch eine solche Bewertungsrichtlinie anwendet, dass den Schülern, die 90 Punkte oder mehr erhalten haben, A und den anderen B zugewiesen werden, sollte er wahrscheinlich einen SAX-Parser verwenden. Der Grund dafür ist, dass jeder Schüler, um eine Abschlussnote zu erhalten, nicht auf die Verarbeitung des gesamten Dokuments warten muss. Er könnte einem Schüler sofort eine Note zuweisen, sobald der SAX-Parser die Note dieses Schülers liest. In der obigen Analyse haben wir angenommen, dass der Ausbilder keine eigene Datenstruktur erstellt hat. Was ist, wenn er seine eigene Datenstruktur erstellt, z. B. ein Array von Zeichenfolgen zum Speichern der SSN und ein Array von Ganzzahlen zum Speichern der Punkte? In diesem Fall, Ich denke, SAX ist eine bessere Wahl, bevor dies sowohl Speicher als auch Zeit sparen und dennoch die Arbeit erledigen kann. Nun, noch eine Überlegung zu diesem Beispiel. Was ist, wenn der Ausbilder nicht eine Liste drucken möchte, sondern das Originaldokument mit der aktualisierten Note jedes Schülers zurückspeichert? In diesem Fall sollte ein DOM-Parser eine bessere Wahl sein, unabhängig davon, welche Bewertungsrichtlinie er anwendet. Er muss keine eigene Datenstruktur erstellen. Was er tun muss, ist, zuerst den DOM-Baum zu ändern (dh den Wert auf den Knoten 'grade' zu setzen) und dann den gesamten geänderten Baum zu speichern. Wenn er einen SAX-Parser anstelle eines DOM-Parsers verwendet, muss er in diesem Fall eine Datenstruktur erstellen, die fast so kompliziert ist wie ein DOM-Baum, bevor er die Aufgabe erledigen kann. noch erledigen Sie die Arbeit. Nun, noch eine Überlegung zu diesem Beispiel. Was ist, wenn der Ausbilder nicht eine Liste drucken möchte, sondern das Originaldokument mit der aktualisierten Note jedes Schülers zurückspeichert? In diesem Fall sollte ein DOM-Parser eine bessere Wahl sein, unabhängig davon, welche Bewertungsrichtlinie er anwendet. Er muss keine eigene Datenstruktur erstellen. Was er tun muss, ist, zuerst den DOM-Baum zu ändern (dh den Wert auf den Knoten 'grade' zu setzen) und dann den gesamten geänderten Baum zu speichern. Wenn er einen SAX-Parser anstelle eines DOM-Parsers verwendet, muss er in diesem Fall eine Datenstruktur erstellen, die fast so kompliziert ist wie ein DOM-Baum, bevor er die Aufgabe erledigen kann. noch erledigen Sie die Arbeit. Nun, noch eine Überlegung zu diesem Beispiel. Was ist, wenn der Ausbilder nicht eine Liste drucken möchte, sondern das Originaldokument mit der aktualisierten Note jedes Schülers zurückspeichert? In diesem Fall sollte ein DOM-Parser eine bessere Wahl sein, unabhängig davon, welche Bewertungsrichtlinie er anwendet. Er muss keine eigene Datenstruktur erstellen. Was er tun muss, ist, zuerst den DOM-Baum zu ändern (dh den Wert auf den Knoten 'grade' zu setzen) und dann den gesamten geänderten Baum zu speichern. Wenn er einen SAX-Parser anstelle eines DOM-Parsers verwendet, muss er in diesem Fall eine Datenstruktur erstellen, die fast so kompliziert ist wie ein DOM-Baum, bevor er die Aufgabe erledigen kann. Aber um das Originaldokument mit der aktualisierten Note jedes Schülers wieder zu speichern? In diesem Fall sollte ein DOM-Parser eine bessere Wahl sein, unabhängig davon, welche Bewertungsrichtlinie er anwendet. Er muss keine eigene Datenstruktur erstellen. Was er tun muss, ist, zuerst den DOM-Baum zu ändern (dh den Wert auf den Knoten 'grade' zu setzen) und dann den gesamten geänderten Baum zu speichern. Wenn er einen SAX-Parser anstelle eines DOM-Parsers verwendet, muss er in diesem Fall eine Datenstruktur erstellen, die fast so kompliziert ist wie ein DOM-Baum, bevor er die Aufgabe erledigen kann. Aber um das Originaldokument mit der aktualisierten Note jedes Schülers wieder zu speichern? In diesem Fall sollte ein DOM-Parser eine bessere Wahl sein, unabhängig davon, welche Bewertungsrichtlinie er anwendet. Er muss keine eigene Datenstruktur erstellen. Was er tun muss, ist, zuerst den DOM-Baum zu ändern (dh den Wert auf den Knoten 'grade' zu setzen) und dann den gesamten geänderten Baum zu speichern. Wenn er einen SAX-Parser anstelle eines DOM-Parsers verwendet, muss er in diesem Fall eine Datenstruktur erstellen, die fast so kompliziert ist wie ein DOM-Baum, bevor er die Aufgabe erledigen kann. Knoten) und speichern Sie dann den gesamten geänderten Baum. Wenn er einen SAX-Parser anstelle eines DOM-Parsers verwendet, muss er in diesem Fall eine Datenstruktur erstellen, die fast so kompliziert ist wie ein DOM-Baum, bevor er die Aufgabe erledigen kann. Knoten) und speichern Sie dann den gesamten geänderten Baum. Wenn er einen SAX-Parser anstelle eines DOM-Parsers verwendet, muss er in diesem Fall eine Datenstruktur erstellen, die fast so kompliziert ist wie ein DOM-Baum, bevor er die Aufgabe erledigen kann.

Ein Beispiel

Problemstellung : Schreiben Sie ein Java-Programm, um alle Informationen zu Kreisen zu extrahieren, die Elemente in einem bestimmten XML-Dokument sind. Wir nehmen an, dass jedes Kreiselement drei untergeordnete Elemente (dh x, y und Radius) sowie ein Farbattribut hat. Ein Beispieldokument ist unten angegeben:

<?xml version="1.0"?> 
<!DOCTYPE shapes [
<!ELEMENT shapes (circle)*>
<!ELEMENT circle (x,y,radius)>
<!ELEMENT x (#PCDATA)>
<!ELEMENT y (#PCDATA)>
<!ELEMENT radius (#PCDATA)>
<!ATTLIST circle color CDATA #IMPLIED>
]>

<shapes> 
          <circle color="BLUE"> 
                <x>20</x>
                <y>20</y>
                <radius>20</radius> 
          </circle>
          <circle color="RED" >
                <x>40</x>
                <y>40</y>
                <radius>20</radius> 
          </circle>
</shapes> 

Programmieren Sie mit DOMparser

import java.io.*;
import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;


public class shapes_DOM {
   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers  
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles 

   public static void main(String[] args) {   

      try{
         // create a DOMParser
         DOMParser parser=new DOMParser();
         parser.parse(args[0]);

         // get the DOM Document object
         Document doc=parser.getDocument();

         // get all the circle nodes
         NodeList nodelist = doc.getElementsByTagName("circle");
         numberOfCircles =  nodelist.getLength();

         // retrieve all info about the circles
         for(int i=0; i<nodelist.getLength(); i++) {

            // get one circle node
            Node node = nodelist.item(i);

            // get the color attribute 
            NamedNodeMap attrs = node.getAttributes();
            if(attrs.getLength() > 0)
               color[i]=(String)attrs.getNamedItem("color").getNodeValue();

            // get the child nodes of a circle node 
            NodeList childnodelist = node.getChildNodes();

            // get the x and y value 
            for(int j=0; j<childnodelist.getLength(); j++) {
               Node childnode = childnodelist.item(j);
               Node textnode = childnode.getFirstChild();//the only text node
               String childnodename=childnode.getNodeName(); 
               if(childnodename.equals("x")) 
                  x[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("y")) 
                  y[i]= Integer.parseInt(textnode.getNodeValue().trim());
               else if(childnodename.equals("radius")) 
                  r[i]= Integer.parseInt(textnode.getNodeValue().trim());
            }

         }

         // print the result
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }

      }  catch (Exception e) {e.printStackTrace(System.err);}

    }

}

Programmieren Sie mit SAXparser

import java.io.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import org.apache.xerces.parsers.SAXParser;


public class shapes_SAX extends DefaultHandler {

   static int numberOfCircles = 0;   // total number of circles seen
   static int x[] = new int[1000];   // X-coordinates of the centers
   static int y[] = new int[1000];   // Y-coordinates of the centers
   static int r[] = new int[1000];   // radius of the circle
   static String color[] = new String[1000];  // colors of the circles

   static int flagX=0;    //to remember what element has occurred
   static int flagY=0;    //to remember what element has occurred
   static int flagR=0;    //to remember what element has occurred

   // main method 
   public static void main(String[] args) {   
      try{
         shapes_SAX SAXHandler = new shapes_SAX (); // an instance of this class
         SAXParser parser=new SAXParser();          // create a SAXParser object 
         parser.setContentHandler(SAXHandler);      // register with the ContentHandler 
         parser.parse(args[0]);
      }  catch (Exception e) {e.printStackTrace(System.err);}  // catch exeptions
   }

   // override the startElement() method
   public void startElement(String uri, String localName, 
                       String rawName, Attributes attributes) {
         if(rawName.equals("circle"))                      // if a circle element is seen
            color[numberOfCircles]=attributes.getValue("color");  // get the color attribute 

         else if(rawName.equals("x"))      // if a x element is seen set the flag as 1 
            flagX=1;
         else if(rawName.equals("y"))      // if a y element is seen set the flag as 2
            flagY=1;
         else if(rawName.equals("radius")) // if a radius element is seen set the flag as 3 
            flagR=1;
   }

   // override the endElement() method
   public void endElement(String uri, String localName, String rawName) {
         // in this example we do not need to do anything else here
         if(rawName.equals("circle"))                       // if a circle element is ended 
            numberOfCircles +=  1;                          // increment the counter 
   }

   // override the characters() method
   public void characters(char characters[], int start, int length) {
         String characterData = 
             (new String(characters,start,length)).trim(); // get the text

         if(flagX==1) {        // indicate this text is for <x> element 
             x[numberOfCircles] = Integer.parseInt(characterData);
             flagX=0;
         }
         else if(flagY==1) {  // indicate this text is for <y> element 
             y[numberOfCircles] = Integer.parseInt(characterData);
             flagY=0;
         }
         else if(flagR==1) {  // indicate this text is for <radius> element 
             r[numberOfCircles] = Integer.parseInt(characterData);
             flagR=0;
         }
   }

   // override the endDocument() method
   public void endDocument() {
         // when the end of document is seen, just print the circle info 
         System.out.println("circles="+numberOfCircles);
         for(int i=0;i<numberOfCircles;i++) {
             String line="";
             line=line+"(x="+x[i]+",y="+y[i]+",r="+r[i]+",color="+color[i]+")";
             System.out.println(line);
         }
   }


}

6

In der Praxis: book.xml

<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
</bookstore>
  • DOM präsentiert das XML-Dokument als die folgende Baumstruktur im Speicher.
  • DOM ist W3C-Standard.
  • Der DOM-Parser arbeitet mit dem Dokumentobjektmodell.
  • DOM belegt mehr Speicher, bevorzugt für kleine XML-Dokumente
  • DOM ist einfach vorwärts oder rückwärts zu navigieren.

Geben Sie hier die Bildbeschreibung ein


  • SAX stellt das XML - Dokument als ereignisbasierte wie start element:abc, end element:abc.
  • SAX ist kein W3C-Standard, sondern wurde von einer Gruppe von Entwicklern entwickelt.
  • SAX verwendet keinen Speicher, der für große XML-Dokumente bevorzugt wird.
  • Eine Rückwärtsnavigation ist nicht möglich, da die Dokumente nacheinander verarbeitet werden.
  • Das Ereignis passiert mit einem Knoten / Element und gibt alle Unterknoten an (lateinischer Knoten, 'Knoten').

Wenn dieses XML-Dokument einen SAX-Parser durchläuft, wird eine Folge von Ereignissen wie die folgende generiert :

start element: bookstore
start element: book with an attribute category equal to cooking
start element: title with an attribute lang equal to en
Text node, with data equal to Everyday Italian
....
end element: title
.....
end element: book
end element: bookstore

Warum ist attr: "lang"oben element: <title>in der visuellen Darstellung der DOM-Analyse? Wenn man sich das XML ansieht, sieht es so aus, als ob attres parallel zu seinem <element>wie mit <book>und sein sollte category. Ist das nur eine platzsparende Technik oder ist eine Eltern-Kind-Beziehung beabsichtigt?
1252748

Es ist nur eine platzsparende Technik
Premraj

3

DOM steht für Document Object Model und repräsentiert ein XML-Dokument im Baumformat, wobei jedes Element Baumzweige darstellt. Der DOM-Parser erstellt eine In-Memory-Baumdarstellung der XML-Datei und analysiert sie dann. Daher ist mehr Speicher erforderlich. Es wird empfohlen, die Heap-Größe für den DOM-Parser zu erhöhen, um Java.lang.OutOfMemoryError: Java-Heap-Speicherplatz zu vermeiden. Das Parsen von XML-Dateien mit dem DOM-Parser ist recht schnell, wenn die XML-Datei klein ist. Wenn Sie jedoch versuchen, eine große XML-Datei mit dem DOM-Parser zu lesen, besteht eine höhere Wahrscheinlichkeit, dass es lange dauert oder sogar nicht vollständig geladen werden kann Es erfordert viel Speicher, um einen XML-Dombaum zu erstellen. Java bietet Unterstützung beim DOM-Parsing und Sie können XML-Dateien in Java mithilfe des DOM-Parsers analysieren. DOM-Klassen befinden sich im Paket w3c.dom, während sich DOM Parser für Java im Paket JAXP (Java API for XML Parsing) befindet.

SAX XML Parser in Java

SAX steht für Simple API for XML Parsing. Dies ist eine ereignisbasierte XML-Analyse, bei der XML-Dateien Schritt für Schritt analysiert werden, was für große XML-Dateien sehr gut geeignet ist. SAX XML Parser löst ein Ereignis aus, wenn es auf das Öffnen von Tags, Elementen oder Attributen stößt und die Analyse entsprechend funktioniert. Es wird empfohlen, den SAX XML-Parser zum Parsen großer XML-Dateien in Java zu verwenden, da nicht die gesamte XML-Datei in Java geladen werden muss und eine große XML-Datei in kleinen Teilen gelesen werden kann. Java bietet Unterstützung für SAX-Parser und Sie können jede XML-Datei in Java mit SAX Parser analysieren. Ich habe hier ein Beispiel für das Lesen von XML-Dateien mit SAX Parser behandelt. Ein Nachteil der Verwendung von SAX Parser in Java besteht darin, dass das Lesen von XML-Dateien in Java mit SAX Parser im Vergleich zu DOM Parser mehr Code erfordert.

Unterschied zwischen DOM und SAX XML Parser

Hier sind einige wesentliche Unterschiede zwischen DOM-Parser und SAX-Parser in Java:

1) Der DOM-Parser lädt das gesamte XML-Dokument in den Speicher, während SAX nur einen kleinen Teil der XML-Datei in den Speicher lädt.

2) Der DOM-Parser ist schneller als SAX, da er auf das gesamte XML-Dokument im Speicher zugreift.

3) Der SAX-Parser in Java eignet sich besser für große XML-Dateien als der DOM-Parser, da er nicht viel Speicher benötigt.

4) Der DOM-Parser arbeitet mit dem Dokumentobjektmodell, während SAX ein ereignisbasierter XML-Parser ist.

Lesen Sie mehr: http://javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz2uz1bJQqZ


2

Sowohl SAX als auch DOM werden zum Parsen des XML-Dokuments verwendet. Beides hat Vor- und Nachteile und kann je nach Situation in unserer Programmierung verwendet werden

SAXOPHON:

  1. Analysiert Knoten für Knoten

  2. Speichert das XML nicht im Speicher

  3. Wir können keinen Knoten einfügen oder löschen

  4. Überqueren von oben nach unten

DOM

  1. Speichert das gesamte XML-Dokument vor der Verarbeitung im Speicher

  2. Besetzt mehr Speicher

  3. Wir können Knoten einfügen oder löschen

  4. In jede Richtung fahren.

Wenn wir einen Knoten finden müssen und ihn nicht einfügen oder löschen müssen, können wir SAX selbst verwenden, andernfalls DOM, sofern wir mehr Speicher haben.


1

1) Der DOM-Parser lädt das gesamte XML-Dokument in den Speicher, während SAX nur einen kleinen Teil der XML-Datei in den Speicher lädt.

2) Der DOM-Parser ist schneller als SAX, da er auf das gesamte XML-Dokument im Speicher zugreift.

3) Der SAX-Parser in Java eignet sich besser für große XML-Dateien als der DOM-Parser, da er nicht viel Speicher benötigt.

4) Der DOM-Parser arbeitet mit dem Dokumentobjektmodell, während SAX ein ereignisbasierter XML-Parser ist.

Lesen Sie mehr: http://javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz498y3vPFR

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.