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.
Write PrintHandler
class (extension of DefaultHandler
)
that writes a document as formatted XML (nested elements indentation) to the standard output.
Handle elements with attributes and text nodes. Do not treat special characters specially.
Write a program using that class for a given XML file.
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)
(dla czytelności i przenośności rozwiązania, 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.
Dla plików jak shop2.xml,
napisz filtr SAX (podklasę XMLFilterImpl
), który przepuszcza towary z kategorii podanej jako parametr konstruktora klasy.
PrintHandler
i stwórz program
filtrujący podany plik ze sklepem.
avg
zawierający średnią cenę przepuszczonych towarów.
For files such as shop2.xml,
implement a SAX filter (a subclass of XMLFilterImpl
) that passes through only products from a given (as a parameter) category.
PrintHandler
class written before and make
a program filtering products from a shop.
avg
containing average price from products passed through.
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).