JDom, Xerces, SAX

0

Mam pytanie, bo zaczytuję się już mase czasu w internetowym wodolańsku i nie potrafię znaleźć niczego powiedzianego wprost, czy raczej jak coś znajdę i jestem pewny, że tak jest, to gdzie indziej znajduję coś sprzecznego.

Co to jest Xerces ?? Rozumiem, że to biblioteka pomagająca podczas pracy z XML w Javie. Wiem, że kiedyś był biblioteką oddzielną, a teraz jest w javowym API na stałe. Ale, czy dobrze myślę, że można korzystać z biblioteki JDom, która po prostu usprawnia styl programowania, wykorzystując Xerces (który dodatkowo używa SAXa lub DOMa) ? Czytam dokument tak :

SAXBuilder builder = new SAXBuilder("com.sun.org.apache.xerces.internal.parsers.SAXParser", true);
builder.setFeature ("http://apache.org/xml/features/validation/schema", true);
		
try {
	builder.setProperty ("http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation", 
	new File("XML_Schema.xsd").toURI().toURL().toString());
		} catch (MalformedURLException e) {
			e.printStackTace();
		}

Document doc = (Document) builder.build(file);

com.sun.org.apache.xerces - to jest wyraźne wskazanie na Xercesa .. zdaje się, że JDom domyślnie korzysta z JAXP, ale ja podmieniam (?) na Xerces. No i dalej korzystam z interfejsu SAX. Swoją drogą jak SAXem można czytać dokument ? Po co ? Czy jak bym użył DOMBuildera (bo analogicznie pewnie istnieje) to byłoby wolniej ?

Wszystko działa, ale zastanawiam się nad tym co się właściwie dzieje - czy jest tak jak myślę ?

0

Pierwsza sprawa, to czy JDOM na pewno usprawnia styl programowania? Sprawa dyskusyjna. Biblioteka powstała, żeby obsługa drzewa DOM była zbliżona do obsługi kolekcji. Na chwilę obecną, kiedy istnieje skrócona wersja pętli for i typy generyczne (od java 5) obie biblioteki (Xerces i JDOM) nie zostały do tego dostosowane i pisanie w nich jest takie dziwne, jak w dawnych czasach. Ale to kwestia przyzwyczajenia.
To jakiego parsera używa JDOM nie ma wpływu na dalszą pracę z dokumentem. Nie zdziwiłbym się, gdyby to zaklęcie w konstruktorze ustawiało dokładnie ten parser, który jest domyślnie używany.
Jak utworzyłeś obiekt Document, to już nie korzystasz dalej z interfejsu SAX.
SAX jest parserem zdarzeniowym, wywołuje kolejno metody w odpowiedzi na znaczniki pojawiające się po kolei w pliku tekstowym z dokumentem XML. Po co? Bo tak jest chyba najprościej.
Czy jest tak jak myślisz? Tego to ja nie wiem, nie umiem czytać w myślach :)

0

No myślę tak jak napisałem :]. Ale już wiem. Xerces to parser implementujący SAXa i DOMa - i może z niego korzystać JDOM, bo jak pisze, korzysta z zewnętrznego parsera. Po tym zaklęciu w konstruktorze raczej domyślnego parsera nie będzie używał, o ile rzeczywiście jest nim JAXP :). Pytanie tylko - jaka tego zaleta ?

"Jak utworzyłeś obiekt Document, to już nie korzystasz dalej z interfejsu SAX." no tak .. ale przetwarzając dokumenty parserem implementującym SAX nie zapisuje się ich, więc dziwi mnie to, że jest możliwość zapisania całego dokumentu po przetworzeniu go SAXem - przecież nie od tego jest ... ma działać szybciej właśnie dzięki innemu podejściu do dokumentu niż w przypadku DOM, a to DOM pozwala zapisać dokument, więc co ten SAX w moim kodzie daje ? Czy rzeczywiście szybciej przeczytam dokument ? Bo moim zdaniem nie powinienem go móc zapisać. SAX zapomina o poprzednim elemencie przechodząc do następnego, przez co nie razi tak pamięci jak DOM.

"SAX jest parserem zdarzeniowym, wywołuje kolejno metody w odpowiedzi na znaczniki pojawiające się po kolei w pliku tekstowym z dokumentem XML. Po co? Bo tak jest chyba najprościej." kwestia szybkości, nie prostoty :] - i DOM i SAX są potrzebne, ale każdy ma inne zastosowanie.

Co mi w takim razie usprawnia ten mój SAX w kodzie ? I jak to możliwe, że tak się da zrobić ?

0

PS. No JDOM usprawnia zdecydowanie styl programowania. Zapis do pliku to kwestia jednej linijki, czy dwóch. Nad resztą szczegółów nie chce mi się rozwodzić, ale pisze się wygodniej. Wiem, bo nawet miałem okazje stworzyć ten sam algorytm 2ma metodami.

0

Kolejny wniosek. Jednak SAX daje możliwość zapisania tego, co przetwarza, z taką różnicą, że nadal generuje zdarzenia sekwencyjnie i parsuje na bieżąco. Tak by wynikało z chaosu informacji internetowych.

Ale co go w powyższym przypadku różni od DOMa jeszcze ? Zaletą w odróżnieniu od DOM było to, że był szybszy i mniej pamięciożerny, ale jak się zapisuje dokument, to chyba na tym traci ? To jaka różnica ? Można by nawet powiedzieć, że wykorzystanie parsera SAX w tym przypadku jest bez sensu.

Dobrze piszę ? :]

0

Jak wszystko wiesz, to po co się pytasz?

przetwarzając dokumenty parserem implementującym SAX nie zapisuje się ich, więc dziwi mnie to, że jest możliwość zapisania całego dokumentu po przetworzeniu go SAXem

W JDOM i w DOM parser SAX jest wykorzystywany do zbudowania drzewa DOM, dlatego możesz potem ten dokument zapisać.

Pytanie tylko - jaka tego zaleta ?

Zaleta jest taka, że możesz podać parser inny niż w tym Xercesie, który jest JRE. Wersja do pobrania ze strony projektu nie jest co prawda nowa, ale nowsza niż ta wbudowana. Możesz też użyć innej implementacji niż Xerces.
W tym kodzie co pokazałeś użycie innego parsera nie wydaje mi się konieczne.
Co do stylu programowania, to jest kwestia gustu, ja tam wolę W3C DOM. Fakt, że zapis do pliku to koszmar w porównaniu z JDOM, ale jak się to raz napisze można używać wiecznie. I jeszcze Xerces ma w sobie metody, które pozwalają tak po prostu zapisywać, ale nie są one częścią standardu Java.

0

Kolejne wnioski - prosiłbym o korektę - SAXem można ładować dokument, ale przy odpowiedniej obsłudze zdarzeń możnaby załadować tylko jego fragment. No i dane są tylko do odczytu ? Nie można ich modyfikować ? Jeśli tak, to może faktycznie SAX załaduje dokument szybciej, a mi modyfikacja danych nie jest potrzebna. Wtedy to by nabrało sensu.

"Jak wszystko wiesz, to po co się pytasz? " a wiem ? chce się upewnić. Poza tym - jak pisałem wiedziałem mniej, a w każdym poście pozostawiłem pytanie, więc chyba jasno z tego wynika, że nie wiem wszystkiego.

"W JDOM i w DOM parser SAX jest wykorzystywany do zbudowania drzewa DOM" - nie rozumiem .. jak w DOM parser SAX ?

"Możesz też użyć innej implementacji niż Xerces." pytając jaka tego zaleta nie chodziło mi w ogóle o możliwość zmiany parserów, tylko jaka zaleta płynie konkretnie ze zamiany JAXP na Xerces ?

"I jeszcze Xerces ma w sobie metody, które pozwalają tak po prostu zapisywać, ale nie są one częścią standardu Java." - no to ok, jest jakaś odmiana. Ale chyba jednak w moim kodzie to i tak bezcelowe :)

0
CzarnyNinja napisał(a)

Kolejne wnioski - prosiłbym o korektę - SAXem można ładować dokument, ale przy odpowiedniej obsłudze zdarzeń możnaby załadować tylko jego fragment. No i dane są tylko do odczytu ? Nie można ich modyfikować ? Jeśli tak, to może faktycznie SAX załaduje dokument szybciej, a mi modyfikacja danych nie jest potrzebna. Wtedy to by nabrało sensu.

Właściwie tak z tym, że SAX nie ładuje, a jedynie czyta i generuje zdarzenia. Dopiero jak się obsłuży odpowiednio te zdarzenia można mówić, że coś się ładuje. Przy odpowiedniej obsłudze, tzn. rzucając wyjątek, można przerwać parsowanie po odczytaniu fragmentu. Wtedy załadować możesz np. tylko jedną zmienną, a nie cały dokument

"W JDOM i w DOM parser SAX jest wykorzystywany do zbudowania drzewa DOM" - nie rozumiem .. jak w DOM parser SAX ?

No a jak inaczej? Czytasz plik tekstowy, znak po znaku, w nim nie ma obiektów, są budowane w odpowiedzi na zdarzenia.

"Możesz też użyć innej implementacji niż Xerces." pytając jaka tego zaleta nie chodziło mi w ogóle o możliwość zmiany parserów, tylko jaka zaleta płynie konkretnie ze zamiany JAXP na Xerces ?

To nie jest tak, że zamieniasz JAXP na Xerces. JAXP to tylko interfejs programistyczny, jak sama nazwa wskazuje. Xerces jest jego implementacją. Dzięki temu używając JAXP wskazujesz parser (to magiczne zaklęcie) i dalej już nie musisz się interesować jaki on jest, bo jest zgodny z JAXP. Dlatego pisałem, że zamiana domyślnego na Xerces może nic nie zmieniać.

0

"Czytasz plik tekstowy, znak po znaku, w nim nie ma obiektów, są budowane w odpowiedzi na zdarzenia."

No ok. To czym się różni parser DOMParser od SAXParser, jeśli do budowy drzewa DOM korzysta się z parsera SAX ? Oba są w pakiecie .sun.org.apache.xerces.internal.parsers.

0

Chociaż chyba rozumiem. Po prostu pomyliłem z klasą SAXBuilder JDOMa. Rozumiem, jeśli jest tak - parser SAXParser nie pozwala na zbudowanie modelu obiektów, a parser DOMParser pozwala, zaraz po przeskanowaniu parserem SAX. No ale to zawsze się korzysta z SAX w DOM ? Różnica tylko taka, że w DOMParser nie możesz kontrolować tych zdarzeń, które kontrolujesz używając SAXParser, mimo, że one dla DOMParser i tak zachodzą podczas budowy modelu ?

0

http://www.devx.com/xml/Article/16922/1954

Nadal nie rozumiem stwierdzenia
"w DOM parser SAX jest wykorzystywany do zbudowania drzewa DOM"

"Czytasz plik tekstowy, znak po znaku, w nim nie ma obiektów, są budowane w odpowiedzi na zdarzenia" - DOM nie bazuje na zdarzeniach.

Dla mnie to dwa odrębne interfejsy z różnym sposobem działania parserów. Dodatkowo w linku pisze, że
"In SAX's event-based system, the parser doesn't create any internal representation of the document."

"Using a SAX parser may require you to store information in your own internal document representation if you need to rescan or analyze the information—SAX provides no container for the document like the DOM tree structure"

Czyli SAXBuilder w JDOM tworzy dokument, bo sobie tak twórcy JDOM wymyślili i stworzyli możliwość zapisu na bieżąco do "internal document". W takim razie, czy w taki sposób, jeśli chce odczytać dokument nie korzystając z możliwości przechwytywania zdarzeń (czyli tak jak jest w moim kodzie), SAX nie traci swoich zalet ? Bo i tak staje się pamięciożerny i parsowanie trwa dłużej, skoro SAX musi zapisywać obiekty. Ale tak jak pisałem wcześniej - przy odpowiedniej obsłudze zdarzeń można by stworzyć Document skrócony. Czyli mając do dyspozycji takie dane

<Elem1>
	<Elem11>
		<Elem111/>	
		<Elem112/>
	</Elem11>
	<Elem12/>
</Elem1>
<Elem2/>

nie można by sobie podczas odczytu przefiltrować w zdarzeniach tego tak:

<Elem11>
	<Elem111/>	
</Elem11>
<Elem2/>

tworząc wynikowo dokument z taką właśnie zawartością ? No bo przecież SAX daje możliwość ingerencji w dane (bez modyfikacji, ale z możliwością zapamiętania) na bieżąco - mimo, że sobie w międzyczasie tworzy jakiś JDOMowy Document.

0

Może się trochę źle wyraziłem, parser DOM może wykorzystywać wewnętrznie parser SAX. Tutaj: http://www.javacommerce.com/displaypage.jsp?name=domparser1.sql&id=18232 jest takie stwierdzenie. Chodzi mi o to, że rozróżnienie na parsery DOM i SAX jest zrobione na podstawie wyniku działania, a nie sposobu. W DOM jest to drzewo a w SAX strumień zdarzeń, który może być obsłużony w dowolny sposób (np. do generowania wewnętrznego modelu, który może być drzewem DOM). W SAX nie ma obowiązku przechowywania całego strumienia (jak to ze strumieniem bywa). Dla odmiany DOM udostępnia cały dokument.
SAXBuilder z JDOM jest najlepszym przykładem: wynikiem jest DOM, ale użyty jest SAX do jego inicjalizacji.
Rzeczywiście, można zrobić taką obsługę zdarzeń, żeby filtrować wybrane elementy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1