Wszystkie przykładowe programy:
SAX jest to interfejs programistyczny oparty o zdarzeniowy model dokumentu. Może być zaimplementowany w obiektowych językach programowania, a interfejsy zbliżone do SAX można spotkać także w językach pozwalających na przekazywanie referencji do funkcji (np. C). My zajmiemy się standardową implementacją w Javie.
Cechy charakterystyczne SAX:
API Javy:
org.xml.sax
[.*
], javax.xml.parsers
.Zobacz także:
Pliki: SaxSimplePrinter, InfoHandler.
Program parsuje podany dokument i wypisuje na wyjście informacje o węzłach (niektórych rodzajów). Klasa InfoHandler
jest realizacją interfejsu ContentHandler
, jej obiekty obsługują zdarzenia SAX.
Plik: LiczbySAX.
Program liczy sumę wartości tych elementów l
, które znajdują się w elementach grupa
o atrybucie wazne
równym tak
.
Programista podaje swój kod tworząc klasę implementującą interfejs ContentHandler
.
Parserowi wskazuje się obiekt, który ma obsługiwać zdarzenia, a podczas parsowania metody tego obiektu
wywoływane są w odpowiedzi na zdarzenia takie jak początek elementu czy węzeł tekstowy.
Więcej zdarzeń można obsługiwać, jeśli zaimplementuje się także interfejsy ErrorHandler
(obsługa błędów, m.in. walidacji), LexicalHandler
(obsługa encji, sekcji CDATA, komentarzy),
DeclHandler
(obsługa DTD). Szczegóły w API.
Napisz klasę PrintHandler
(rozszerzenie DefaultHandler
),
której działanie polega na wypisywaniu na wyjście dokumentu w postaci sformatowanej
(większe wcięcia na kolejnych poziomach zagnieżdżenia elementów).
Wystarczy wypisywać elementy z atrybutami i węzły tekstowe, nie należy przejmować się znakami specjalnymi.
Użyj tej klasy w programie parsującym w trybie SAX i wypisującym w opisany wyżej sposób dowolny dokument.
Podobnie jak w DOM, w SAX możemy przetwarzać dokument uwzględniając lub nie przestrzenie nazw.
Jeśli nie chcemy uwzględniać przestrzeni nazw, powinniśmy:
setNamespaceAware(false)
(tak naprawdę to jest domyślna wartość),qName
w metodzie startElement
i metodą getQName
dla atrybutów.Jeśli chcemy uwzględniać przestrzenie nazw, powinniśmy:
setNamespaceAware(true)
,uri
i localName
w metodzie startElement
oraz metodami getURI
i getLocalName
dla atrybutów.
W pewnych sytuacjach użyteczne mogą być też nazwy kwalifikowane (z ewentualnym prefiksem),
ale to para (uri, localName) decyduje o znaczeniu elementu bądź atrybutu.
Filtr to obiekt klasy implementującej interfejs XMLFilter
(można rozszerzać standardową klasę XMLFilterImpl
).
Obiekt taki można umieścić między parserem a ContentHandler
-em,
z punktu widzenia „handlera” działa on jak parser (można wywołać na nim metodę parse
,
on wywołuje metody „handlera”), natomiast z punktu widzenia parsera zachowuje się on jak „handler”
– parser wywołuje metody filtra.
Filtry można łączyć w łańcuchy (metoda setParent
), każdy filtr może filtrować lub modyfikować zdarzenia,
a także wykonywać pewne czynności / obliczenia. Dzięki temu podczas jednego parsowania
dokumentu można wykonać wiele czynności.
XMLReader parser = XMLReaderFactory.getXMLReader(); ContentHandler handler = new MyHandler(); XMLFilter filtr = new MyFilter(); filtr.setParent(parser); filtr.setContentHandler(handler); filtr.parse();
Plik: FiltrySAX.
Prosty przykład użycia filtra SAX. Filtr przepuszcza tylko niepuste węzły tekstowe i zmienia wielkość liter w nazwach elementów.
Zadanie dotyczy przykładu z wykładu i dokumentów takich jak liczby.xml.
Wykorzystaj klasę LiczbyFiltr
, która implementuje filtr SAX przepuszczający tylko grupy o atrybucie ważne równym tak
i ich zawartość (podelementy i tekst),
natomiast zatrzymujący nieważne grupy i ich zawartość.
PrintHandler
i ułóż program
wypisujący przefiltrowany dokument z liczbami.
l
w ważnych grupach. Niech filtr przepuszcza tylko ważne grupy i ich zawartość, a prostszy niż do tej pory handler zlicza wszystkie liczby.
suma
zawierający sumę liczb z tej grupy. Połącz taki filtr z handlerem wypisującym (napisanym na początku zajęć).
Dokumenty można walidować podczas parsowania w trybie SAX.
Najprościej walidować dokument względem jego DTD (wystarczy ustawić w fabryce parserów setValidating(true)
).
Walidacja względem XML Schema wymaga niewielkich dodatkowych zabiegów (podobnych jak dla DOM).