Jaka jest różnica między SAX a DOM?

242

Przeczytałem kilka artykułów o parserach XML i natknąłem się na SAX i DOM .

SAX jest oparty na zdarzeniach, a DOM to model drzewa - nie rozumiem różnic między tymi pojęciami.

Z tego, co zrozumiałem, oparty na zdarzeniu oznacza, że ​​w węźle dzieje się jakieś zdarzenie. Podobnie jak po kliknięciu określonego węzła, wszystkie węzły zostaną podane, zamiast ładowania wszystkich węzłów w tym samym czasie. Ale w przypadku analizowania DOM ładuje wszystkie węzły i tworzy model drzewa.

Czy moje rozumowanie jest prawidłowe?

Proszę mnie poprawić Jeśli się mylę lub wyjaśnij mi model oparty na zdarzeniach i drzewie w prostszy sposób.

użytkownik414967
źródło
Prawidłowo mówiąc DOM nie jest analizatorem składni. Każde oprogramowanie oparte na modelu DOM może, ale nie musi, zawierać analizy składni znaczników, a większość oprogramowania DOM w HTML to robi. Ale DOM jest całkowicie odrębną rzeczą, która może nie być w ogóle powiązana z żadnym formatem serializacji.
Bob77

Odpowiedzi:

305

Jesteś blisko.

W SAX zdarzenia są wyzwalane podczas analizowania XML . Gdy analizator składni analizuje plik XML i napotka znacznik rozpoczynający się (np. <something>), Wówczas wyzwala tagStartedzdarzenie (rzeczywista nazwa zdarzenia może się różnić). Podobnie, gdy koniec tagu jest spełniony podczas parsowania ( </something>), uruchamia się tagEnded. Korzystanie z analizatora składni SAX wymaga obsługi tych zdarzeń i zrozumienia danych zwracanych przy każdym zdarzeniu.

W DOM nie ma żadnych zdarzeń wyzwalanych podczas analizy. Cały plik XML jest analizowany, a drzewo DOM (węzłów w pliku XML) jest generowane i zwracane. Po przeanalizowaniu użytkownik może poruszać się po drzewie, aby uzyskać dostęp do różnych danych wcześniej osadzonych w różnych węzłach XML.

Ogólnie rzecz biorąc, DOM jest łatwiejszy w użyciu, ale ma narzut związany z analizowaniem całego XML, zanim zaczniesz go używać.

Sparkymat
źródło
135
+1 - aby wyjaśnić: użyj parsera DOM z mniejszymi plikami, które mieszczą się w pamięci RAM. Użyj analizatora składni SAX dla dużych plików, które nie będą.
Richard H
dzięki @spartkymat. Ale czy w przypadku opartego na zdarzeniach SAX parser SAX będzie mógł wiedzieć, że określony węzeł potomny jest dzieckiem określonego rodzica? Czy po prostu się sparsuje? na przykład. Mam jedną <firma>, a dziecko jest <pracownikiem>. Więc w tym przypadku ta firma i pracownik zostaną po prostu przeanalizowani, czy pokaże relację, że firma jest rodzicem pracownika?
user414967
4
To tylko parsuje. Będziesz musiał zachować takie informacje samodzielnie (za pośrednictwem automatu stanowego lub w inny sposób). Tym bardziej powód do korzystania z parsera DOM (jeśli pozwalają na to zasoby) :-).
sparkymat
1
@Richard H Twierdziłbym, że każdy, kto używa plików XML tak dużych, że nie zmieści się w pamięci RAM, robi coś bardzo bardzo złego.
antred
1
załaduj program Excel o rozmiarze 40 m, użyj 200 m pamięci, gdy używasz parsera SAX, ale użyj 9 g pamięci, gdy używasz parsera DOM.
zhiyuan_
98

W kilku słowach ...

SAX ( S wyko A PI X ML): jest to procesor strumieniowej. W każdej chwili masz tylko niewielką część pamięci i „wąchasz” strumień XML, implementując kod wywołania zwrotnego dla zdarzeń takich jak tagStarted()itp. Nie używa prawie żadnej pamięci, ale nie możesz robić rzeczy „DOM”, takich jak użycie xpath lub traverse drzewa.

DOM ( D ocument O bject M Odel): załadować całość w pamięci - to ogromny wieprz pamięci. Możesz wysadzić pamięć nawet w dokumenty średniej wielkości. Ale możesz użyć xpath i przejść przez drzewo itp.

Czeski
źródło
66

Tutaj w prostszych słowach:

DOM

  • Parser modelu drzewa (obiektowy) (Tree of nodes).

  • DOM ładuje plik do pamięci, a następnie analizuje plik.

  • Ma ograniczenia pamięci, ponieważ ładuje cały plik XML przed analizą.

  • DOM jest odczytywany i zapisywany (może wstawiać lub usuwać węzły).

  • Jeśli zawartość XML jest mała, wybierz parser DOM.

  • Wyszukiwanie do tyłu i do przodu jest możliwe w celu przeszukiwania znaczników i oceny informacji wewnątrz znaczników. Daje to łatwość nawigacji.

  • Wolniej w czasie wykonywania.

SAX

  • Parser oparty na zdarzeniu (sekwencja zdarzeń).

  • SAX analizuje plik podczas jego odczytu, tzn. Analizuje węzeł po węźle.

  • Brak ograniczeń pamięci, ponieważ nie przechowuje treści XML w pamięci.

  • SAX jest tylko do odczytu, tzn. Nie można wstawić ani usunąć węzła.

  • Użyj parsera SAX, gdy zawartość pamięci jest duża.

  • SAX odczytuje plik XML od góry do dołu i nawigacja do tyłu nie jest możliwa.

  • Szybszy w czasie wykonywania.

Chinmoy Mishra
źródło
idealne ... spodziewał się odpowiedzi w punktach. Dobra robota :)
Kunal Gupta
37

Masz rację, rozumiejąc model oparty na DOM. Plik XML zostanie załadowany jako całość, a cała jego zawartość zostanie zbudowana jako reprezentacja w drzewie drzewa reprezentowanego przez dokument. Może to zająć dużo czasu i pamięci, w zależności od wielkości pliku wejściowego. Zaletą tego podejścia jest to, że można łatwo wyszukiwać w dowolnej części dokumentu i swobodnie manipulować wszystkimi węzłami w drzewie.

Podejście DOM jest zwykle stosowane w przypadku małych struktur XML (gdzie małe zależą od mocy i pamięci posiadanej platformy), które mogą wymagać modyfikacji i zapytań na różne sposoby po ich załadowaniu.

Z drugiej strony SAX jest zaprojektowany do obsługi danych wejściowych XML praktycznie dowolnego rozmiaru. Zamiast frameworka XML, który wykonuje ciężką pracę za opracowanie struktury dokumentu i przygotowanie potencjalnie wielu obiektów dla wszystkich węzłów, atrybutów itp., SAX całkowicie to pozostawia.

W zasadzie odczytuje dane wejściowe z góry i wywołuje metody wywołania zwrotnego, które podajesz, gdy wystąpią pewne „zdarzenia”. Wydarzenie może uderzać w otwierający tag, atrybut w tagu, znajdować tekst w elemencie lub napotykać tag końcowy.

SAX uparcie czyta dane wejściowe i mówi ci, co widzi w ten sposób. Do ciebie należy utrzymanie wszystkich wymaganych informacji o stanie. Zwykle oznacza to, że zbudujesz jakąś maszynę stanu.

Chociaż takie podejście do przetwarzania XML jest znacznie bardziej nużące, może być również bardzo wydajne. Wyobraź sobie, że chcesz po prostu wyodrębnić tytuły artykułów z blogu. Jeśli przeczytasz ten XML za pomocą DOM, załaduje on całą zawartość artykułu, wszystkie obrazy itp. Zawarte w XML do pamięci, nawet jeśli nawet go nie interesujesz.

Za pomocą SAX możesz po prostu sprawdzić, czy nazwa elementu to (np.) „Tytuł” ​​za każdym razem, gdy wywoływana jest metoda zdarzenia „startTag”. Jeśli tak, wiesz, że musisz dodać wszystko, co oferuje następne zdarzenie „elementText”. Po odebraniu wywołania zdarzenia „endTag” ponownie sprawdzisz, czy jest to element zamykający „tytuł”. Następnie po prostu zignoruj ​​wszystkie dalsze elementy, dopóki dane wejściowe się nie zakończą lub pojawi się kolejny „startTag” o nazwie „tytuł”. I tak dalej...

W ten sposób możesz odczytać megabajty i megabajty XML, po prostu wyodrębniając niewielką ilość potrzebnych danych.

Negatywną stroną tego podejścia jest oczywiście to, że musisz sam zrobić znacznie więcej księgowości, w zależności od tego, jakie dane musisz wyodrębnić i jak skomplikowana jest struktura XML. Co więcej, naturalnie nie możesz modyfikować struktury drzewa XML, ponieważ nigdy nie masz go pod ręką jako całości.

Ogólnie rzecz biorąc, SAX nadaje się do przeczesywania potencjalnie dużych ilości danych, które otrzymujesz z myślą o konkretnym „zapytaniu”, ale nie trzeba go modyfikować, podczas gdy DOM jest bardziej ukierunkowany na zapewnienie pełnej elastyczności w zmianie struktury i treści, kosztem większego zapotrzebowania na zasoby.

Daniel Schneller
źródło
16

Porównujesz jabłka i gruszki. SAX to analizator składni, który analizuje zserializowane struktury DOM. Istnieje wiele różnych parserów, a „oparty na zdarzeniu” odnosi się do metody parsowania.

Może jest małe podsumowanie:

  • Model obiektowy dokumentu (DOM) to abstrakcyjny model danych opisujący hierarchiczną strukturę dokumentu opartą na drzewach; drzewo dokumentu składa się z węzłów , a mianowicie węzłów elementowych, atrybutowych i tekstowych (i niektórych innych). Węzły mają rodziców, rodzeństwo i dzieci i można nimi przechodzić itd., Wszystkie rzeczy, do których przywykłeś robić JavaScript (co zresztą nie ma nic wspólnego z DOM).

  • Struktura DOM może być serializowana , tzn. Zapisywana do pliku, przy użyciu języka znaczników, takiego jak HTML lub XML. Plik HTML lub XML zawiera zatem wersję „spisaną” lub „spłaszczoną” abstrakcyjnego drzewa dokumentów.

  • Aby komputer mógł manipulować, a nawet wyświetlać drzewo DOM z pliku, musi dokonać deserializacji lub parsowania pliku i zrekonstruowania drzewa abstrakcyjnego w pamięci. Tu właśnie pojawia się parsowanie.

Teraz dochodzimy do natury parserów. Jednym ze sposobów analizowania byłoby odczytanie całego dokumentu i rekurencyjne zbudowanie struktury drzewa w pamięci, a na koniec udostępnienie całego wyniku użytkownikowi. (Przypuszczam, że można nazwać te parsery „parserami DOM”.) Byłoby to bardzo przydatne dla użytkownika (myślę, że tak właśnie działa parser XML PHP), ale cierpi z powodu problemów ze skalowalnością i staje się bardzo drogi dla dużych dokumentów.

Z drugiej strony, parsowanie oparte na zdarzeniach , tak jak robi to SAX, patrzy na plik liniowo i po prostu wywołuje oddzwonienie do użytkownika za każdym razem, gdy napotyka strukturalny fragment danych, taki jak „ten element rozpoczęty”, „ten element zakończył się” , „trochę tekstu tutaj” itp. Ma to tę zaletę, że może trwać wiecznie bez względu na rozmiar pliku wejściowego, ale jest o wiele bardziej niski, ponieważ wymaga od użytkownika wykonania całej faktycznej pracy przetwarzania (poprzez zapewnienie oddzwanianie). Aby powrócić do pierwotnego pytania, termin „oparty na zdarzeniu” odnosi się do tych analizowanych zdarzeń, które analizator wywołuje podczas przeglądania pliku XML.

Artykuł w Wikipedii zawiera wiele szczegółów na temat etapów parsowania SAX.

Kerrek SB
źródło
11

Udzielę ogólnej odpowiedzi na pytania i odpowiedzi dotyczące tego pytania:

Odpowiedz na pytania

Dlaczego potrzebujemy parsera XML?

Potrzebujemy parsera XML, ponieważ nie chcemy robić wszystkiego w naszej aplikacji od zera i potrzebujemy programów pomocniczych lub bibliotek, aby zrobić coś bardzo niskiego, ale dla nas bardzo potrzebnego. Te niskiego poziomu, ale niezbędne rzeczy, obejmują sprawdzanie poprawności sformułowania, sprawdzanie poprawności dokumentu pod kątem jego DTD lub schematu (tylko w celu sprawdzania poprawności parserów), rozwiązywanie odniesień do znaków, zrozumienie sekcji CDATA i tak dalej. Parsery XML są właśnie takimi „programami pomocniczymi” i wykonają wszystkie te zadania. Dzięki parserowi XML jesteśmy chronieni przed wieloma z tych złożoności i moglibyśmy skoncentrować się na samym programowaniu na wysokim poziomie za pośrednictwem interfejsów API implementowanych przez parsery, a tym samym uzyskać wydajność programowania.

Który z nich jest lepszy, SAX lub DOM?

Parser SAX i DOM mają swoje zalety i wady. Który z nich jest lepszy, powinien zależeć od cech twojej aplikacji (zapoznaj się z niektórymi pytaniami poniżej).

Który parser może uzyskać lepszą parser prędkości, DOM lub SAX?

Parser SAX może uzyskać lepszą prędkość.

Jaka jest różnica między interfejsem API opartym na drzewie a interfejsem API opartym na zdarzeniach?

Interfejs API oparty na drzewie jest skoncentrowany wokół struktury drzewa i dlatego zapewnia interfejsy na komponentach drzewa (którym jest dokument DOM), takich jak interfejs dokumentu, interfejs węzła, interfejs NodeList, interfejs elementu, interfejs Attr i tak dalej. Natomiast interfejs API oparty na zdarzeniach zapewnia interfejsy w modułach obsługi. Istnieją cztery interfejsy obsługi, interfejs ContentHandler, interfejs DTDHandler, interfejs EntityResolver i interfejs ErrorHandler.

Jaka jest różnica między parserem DOM a parserem SAX?

Parsery DOM i parsery SAX działają na różne sposoby:

  • Analizator składni DOM tworzy strukturę drzewa w pamięci z dokumentu wejściowego, a następnie czeka na żądania od klienta. Ale parser SAX nie tworzy żadnej wewnętrznej struktury. Zamiast tego przyjmuje występowanie elementów dokumentu wejściowego jako zdarzenia i informuje klienta, co czyta, czytając dokument wejściowy. ZA

  • Analizator składni DOM zawsze obsługuje aplikację kliencką z całym dokumentem, bez względu na to, ile tak naprawdę jest potrzebne klientowi. Ale parser SAX obsługuje aplikację kliencką zawsze tylko z fragmentami dokumentu w danym momencie.

  • W parserze DOM wywołania metod w aplikacji klienckiej muszą być jawne i tworzą rodzaj łańcucha. Ale w SAX niektóre pewne metody (zwykle zastępowane przez klienta) będą wywoływane automatycznie (domyślnie) w sposób, który nazywa się „callback”, gdy wystąpią pewne określone zdarzenia. Te metody nie muszą być jawnie wywoływane przez klienta, chociaż możemy je wywoływać jawnie.

Jak decydujemy, który parser jest dobry?

Idealnie dobry parser powinien być szybki (oszczędny czasowo), zajmujący mało miejsca, bogaty w funkcjonalność i łatwy w użyciu. Ale w rzeczywistości żaden z głównych parserów nie ma wszystkich tych funkcji jednocześnie. Na przykład, parser DOM ma bogatą funkcjonalność (ponieważ tworzy drzewo DOM w pamięci i pozwala na wielokrotny dostęp do dowolnej części dokumentu oraz pozwala modyfikować drzewo DOM), ale jest mało miejsca, gdy dokument jest ogromny , a nauka jego obsługi zajmuje trochę czasu. Parser SAX jest jednak znacznie bardziej wydajny w przypadku dużego dokumentu wejściowego (ponieważ nie tworzy wewnętrznej struktury). Co więcej, działa szybciej i jest łatwiejszy do nauki niż DOM Parser, ponieważ jego interfejs API jest naprawdę prosty. Ale z punktu widzenia funkcjonalności zapewnia mniej funkcji, co oznacza, że ​​sami użytkownicy muszą więcej się zajmować, na przykład tworzenie własnych struktur danych. Nawiasem mówiąc, co to jest dobry parser? Myślę, że odpowiedź naprawdę zależy od cech twojej aplikacji.

Jakie są niektóre aplikacje w świecie rzeczywistym, w których korzystanie z analizatora składni SAX jest korzystniejsze niż w przypadku analizatora składni DOM i odwrotnie? Jaka jest typowa aplikacja dla analizatora składni DOM i analizatora składni SAX?

W następujących przypadkach użycie parsera SAX jest korzystniejsze niż użycie parsera DOM.

  • Dokument wejściowy jest zbyt duży, aby pomieścić dostępną pamięć (w tym przypadku jedynym wyborem jest SAX)
  • Możesz przetwarzać dokument w małych, ciągłych fragmentach danych wejściowych. Nie potrzebujesz całego dokumentu, zanim będziesz mógł wykonać przydatną pracę
  • Po prostu chcesz użyć parsera do wyodrębnienia interesujących informacji, a całe twoje obliczenia będą całkowicie oparte na strukturach danych stworzonych przez ciebie. W rzeczywistości w większości naszych aplikacji tworzymy własne struktury danych, które zwykle nie są tak skomplikowane jak drzewo DOM. Z tego punktu widzenia myślę, że szansa na użycie parsera DOM jest mniejsza niż przy użyciu parsera SAX.

W następujących przypadkach użycie parsera DOM jest korzystniejsze niż użycie parsera SAX.

  • Twoja aplikacja musi jednocześnie uzyskiwać dostęp do osobnych części dokumentu.
  • Twoja aplikacja prawdopodobnie korzysta z wewnętrznej struktury danych, która jest prawie tak skomplikowana jak sam dokument.
  • Twoja aplikacja musi wielokrotnie modyfikować dokument.
  • Twoja aplikacja musi przechowywać dokument przez dłuższy czas za pomocą wielu wywołań metod.

Przykład (użyć parsera DOM lub parsera SAX?):

Załóżmy, że instruktor ma dokument XML zawierający wszystkie dane osobowe uczniów, a także punkty, które jego uczniowie zrobili w swojej klasie, i teraz przypisuje końcowe oceny uczniom używającym aplikacji. To, co chce stworzyć, to lista z SSN i ​​ocenami. Zakładamy również, że w swojej aplikacji instruktor nie używa struktury danych, takiej jak tablice, do przechowywania danych osobowych uczniów i punktów. Jeśli instruktor zdecyduje się dać A tym, którzy zdobyli klasę średnią lub wyższą, i dać B innym, wtedy lepiej użyć parsera DOM w swojej aplikacji. Powodem jest to, że nie ma sposobu, aby dowiedzieć się, ile wynosi średnia klasowa, zanim cały dokument zostanie przetworzony. To, co prawdopodobnie powinien zrobić w swoim zgłoszeniu, to najpierw przejrzeć listę wszystkich uczniów punktów i oblicz średnią, a następnie ponownie przejrzyj dokument i przypisz ocenę końcową każdemu uczniowi, porównując zdobyte punkty ze średnią klasową. Jeśli jednak instruktor przyjmie takie zasady oceniania, że ​​uczniom, którzy uzyskali 90 punktów lub więcej, przypisuje się A, a pozostałym przypisuje się B, to prawdopodobnie lepiej użyje parsera SAX. Powodem jest to, że aby przypisać każdemu uczniowi ocenę końcową, nie musi on czekać na przetworzenie całego dokumentu. Mógłby natychmiast przypisać ocenę uczniowi, gdy parser SAX odczyta ocenę tego ucznia. W powyższej analizie przyjęliśmy, że instruktor nie stworzył własnej struktury danych. Co jeśli utworzy własną strukturę danych, taką jak tablica ciągów do przechowywania SSN i ​​tablica liczb całkowitych do przechowywania punktów? W tym przypadku, Myślę, że SAX jest lepszym wyborem, zanim pozwoli to zaoszczędzić zarówno pamięć, jak i czas, a jednocześnie wykonać zadanie. Cóż, jeszcze jedna uwaga na tym przykładzie. Co jeśli instruktor chce nie wydrukować listy, ale zapisać oryginalny dokument z aktualizacją ocen każdego ucznia? W takim przypadku parser DOM powinien być lepszym wyborem, bez względu na to, jakie zasady oceniania przyjmuje. Nie musi tworzyć własnej struktury danych. To, co musi zrobić, to najpierw zmodyfikować drzewo DOM (tj. Ustawić wartość w węźle „ocena”), a następnie zapisać całe zmodyfikowane drzewo. Jeśli zdecyduje się użyć parsera SAX zamiast parsera DOM, wówczas w tym przypadku musi utworzyć strukturę danych, która jest prawie tak skomplikowana jak drzewo DOM, zanim będzie mógł wykonać zadanie. ale załatw robotę. Cóż, jeszcze jedna uwaga na tym przykładzie. Co jeśli instruktor chce nie wydrukować listy, ale zapisać oryginalny dokument z aktualizacją ocen każdego ucznia? W takim przypadku parser DOM powinien być lepszym wyborem, bez względu na to, jakie zasady oceniania przyjmuje. Nie musi tworzyć własnej struktury danych. To, co musi zrobić, to najpierw zmodyfikować drzewo DOM (tj. Ustawić wartość w węźle „ocena”), a następnie zapisać całe zmodyfikowane drzewo. Jeśli zdecyduje się użyć parsera SAX zamiast parsera DOM, wówczas w tym przypadku musi utworzyć strukturę danych, która jest prawie tak skomplikowana jak drzewo DOM, zanim będzie mógł wykonać zadanie. ale załatw robotę. Cóż, jeszcze jedna uwaga na tym przykładzie. Co jeśli instruktor chce nie wydrukować listy, ale zapisać oryginalny dokument z aktualizacją ocen każdego ucznia? W takim przypadku parser DOM powinien być lepszym wyborem, bez względu na to, jakie zasady oceniania przyjmuje. Nie musi tworzyć własnej struktury danych. To, co musi zrobić, to najpierw zmodyfikować drzewo DOM (tj. Ustawić wartość w węźle „ocena”), a następnie zapisać całe zmodyfikowane drzewo. Jeśli zdecyduje się użyć parsera SAX zamiast parsera DOM, wówczas w tym przypadku musi utworzyć strukturę danych, która jest prawie tak skomplikowana jak drzewo DOM, zanim będzie mógł wykonać zadanie. ale żeby zapisać oryginalny dokument z powrotem z oceną każdego ucznia? W takim przypadku parser DOM powinien być lepszym wyborem, bez względu na to, jakie zasady oceniania przyjmuje. Nie musi tworzyć własnej struktury danych. To, co musi zrobić, to najpierw zmodyfikować drzewo DOM (tj. Ustawić wartość w węźle „ocena”), a następnie zapisać całe zmodyfikowane drzewo. Jeśli zdecyduje się użyć parsera SAX zamiast parsera DOM, wówczas w tym przypadku musi utworzyć strukturę danych, która jest prawie tak skomplikowana jak drzewo DOM, zanim będzie mógł wykonać zadanie. ale żeby zapisać oryginalny dokument z powrotem z oceną każdego ucznia? W takim przypadku parser DOM powinien być lepszym wyborem, bez względu na to, jakie zasady oceniania przyjmuje. Nie musi tworzyć własnej struktury danych. To, co musi zrobić, to najpierw zmodyfikować drzewo DOM (tj. Ustawić wartość w węźle „ocena”), a następnie zapisać całe zmodyfikowane drzewo. Jeśli zdecyduje się użyć parsera SAX zamiast parsera DOM, wówczas w tym przypadku musi utworzyć strukturę danych, która jest prawie tak skomplikowana jak drzewo DOM, zanim będzie mógł wykonać zadanie. węzeł), a następnie zapisz całe zmodyfikowane drzewo. Jeśli zdecyduje się użyć parsera SAX zamiast parsera DOM, wówczas w tym przypadku musi utworzyć strukturę danych, która jest prawie tak skomplikowana jak drzewo DOM, zanim będzie mógł wykonać zadanie. węzeł), a następnie zapisz całe zmodyfikowane drzewo. Jeśli zdecyduje się użyć parsera SAX zamiast parsera DOM, wówczas w tym przypadku musi utworzyć strukturę danych, która jest prawie tak skomplikowana jak drzewo DOM, zanim będzie mógł wykonać zadanie.

Przykład

Opis problemu : Napisz program Java, aby wyodrębnić wszystkie informacje o kręgach, które są elementami w danym dokumencie XML. Zakładamy, że każdy element koła ma trzy elementy potomne (tj. X, y i promień), a także atrybut koloru. Przykładowy dokument podano poniżej:

<?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> 

Program z DOMparserem

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);}

    }

}

Program z 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);
         }
   }


}
Humoyun Ahmad
źródło
6

W praktyce: 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 przedstawia dokument xml jako następującą strukturę drzewa w pamięci.
  • DOM jest standardem W3C.
  • Parser DOM działa na modelu obiektowym dokumentu.
  • DOM zajmuje więcej pamięci, preferowane w przypadku małych dokumentów XML
  • DOM jest łatwy w nawigacji do przodu lub do tyłu.

wprowadź opis zdjęcia tutaj


  • SAX prezentuje dokument XML jako zdarzenia opartego jak start element:abc, end element:abc.
  • SAX nie jest standardem W3C, został opracowany przez grupę programistów.
  • SAX nie wykorzystuje pamięci, preferowanej w przypadku dużych dokumentów XML.
  • Nawigacja do tyłu nie jest możliwa, ponieważ sekwencyjnie przetwarza dokumenty.
  • Zdarzenie dzieje się z węzłem / elementem i daje wszystkie podwęzły (węzeł łaciński, „węzeł”).

Ten dokument XML przekazany przez analizator składni SAX wygeneruje sekwencję zdarzeń takich jak :

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
Premraj
źródło
dlaczego jest attr: "lang"wyżej element: <title>w wizualnej reprezentacji parsowania DOM? Patrząc na XML, wygląda na to, że attrpowinien być równoległy do ​​niego, <element>podobnie jak w przypadku <book>i category. Czy to tylko technika oszczędzająca miejsce, czy też istnieje związek rodzic-dziecko?
1252748,
to tylko technika oszczędzająca miejsce
Premraj
3

DOM oznacza Document Object Model i reprezentuje dokument XML w formacie drzewa, w którym każdy element reprezentuje gałęzie drzewa. Parser DOM tworzy reprezentację drzewa XML w pliku XML, a następnie analizuje go, więc wymaga więcej pamięci i wskazane jest zwiększenie wielkości sterty dla analizatora DOM, aby uniknąć Java.lang.OutOfMemoryError: przestrzeń sterty java. Analizowanie pliku XML za pomocą parsera DOM jest dość szybkie, jeśli plik XML jest mały, ale jeśli spróbujesz odczytać duży plik XML za pomocą parsera DOM, istnieje większe prawdopodobieństwo, że zajmie to dużo czasu, a nawet może nie być w stanie załadować go całkowicie, ponieważ wymaga dużo pamięci do stworzenia XML Dom Tree. Java zapewnia obsługę analizowania DOM i można analizować pliki XML w Javie za pomocą analizatora DOM. Klasy DOM znajdują się w pakiecie w3c.dom, podczas gdy DOM Parser dla Java znajduje się w pakiecie JAXP (Java API for XML Parsing).

Parser SAX XML w Javie

SAX oznacza prosty interfejs API do analizowania XML. To parsowanie XML oparte na zdarzeniu, które analizuje plik XML krok po kroku, tak bardzo odpowiedni dla dużych plików XML. Parser SAX XML uruchamia zdarzenie, gdy napotkał otwierający tag, element lub atrybut, a parsowanie działa odpowiednio. Zaleca się użycie parsera XML SAX do analizowania dużych plików XML w Javie, ponieważ nie wymaga on ładowania całego pliku XML w Javie i może odczytać duży plik XML w małych częściach. Java zapewnia wsparcie dla parsera SAX i możesz parsować dowolny plik xml w Javie za pomocą SAX Parsera, omówiłem tutaj przykład odczytu pliku xml przy użyciu Parsera SAX. Jedną wadą używania SAX Parsera w Javie jest to, że czytanie pliku XML w Javie przy użyciu SAX Parsera wymaga więcej kodu w porównaniu z DOM Parserem.

Różnica między DOM a SAX XML Parserem

Oto kilka różnic wysokiego poziomu między analizatorem DOM i analizatorem SAX w Javie:

1) Analizator składni DOM ładuje cały dokument xml do pamięci, podczas gdy SAX ładuje tylko niewielką część pliku XML do pamięci.

2) Parser DOM jest szybszy niż SAX, ponieważ ma dostęp do całego dokumentu XML w pamięci.

3) Parser SAX w Javie jest bardziej odpowiedni dla dużych plików XML niż DOM Parser, ponieważ nie wymaga dużo pamięci.

4) Analizator składni DOM działa na modelu obiektowym dokumentu, podczas gdy SAX to analizator składni xml oparty na zdarzeniu.

Czytaj więcej: http://javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz2uz1bJQqZ

upender
źródło
2

Zarówno SAX, jak i DOM są używane do analizowania dokumentu XML. Oba mają zalety i wady i mogą być wykorzystane w naszym programowaniu w zależności od sytuacji

SAX:

  1. Analizuje węzeł po węźle

  2. Nie przechowuje XML w pamięci

  3. Nie możemy wstawić ani usunąć węzła

  4. Przejście od góry do dołu

DOM

  1. Przechowuje cały dokument XML w pamięci przed przetwarzaniem

  2. Zajmuje więcej pamięci

  3. Możemy wstawiać lub usuwać węzły

  4. Przemierzaj w dowolnym kierunku.

Jeśli musimy znaleźć węzeł i nie musimy go wstawiać ani usuwać, możemy przejść z samym SAX, w przeciwnym razie DOM zapewni nam więcej pamięci.

Kavita Jain
źródło
1

1) Analizator składni DOM ładuje cały dokument XML do pamięci, podczas gdy SAX ładuje tylko niewielką część pliku XML do pamięci.

2) Parser DOM jest szybszy niż SAX, ponieważ ma dostęp do całego dokumentu XML w pamięci.

3) Parser SAX w Javie jest bardziej odpowiedni dla dużych plików XML niż DOM Parser, ponieważ nie wymaga dużo pamięci.

4) Parser DOM działa na modelu obiektowym dokumentu, podczas gdy SAX jest parserem XML opartym na zdarzeniach.

Czytaj więcej: http://javarevisited.blogspot.com/2011/12/difference-between-dom-and-sax-parsers.html#ixzz498y3vPFR

użytkownik6359304
źródło