Przetwarzanie dokumentów XML i zaawansowane techniki WWW Wykład 06



Podobne dokumenty
Wykorzystywanie parsera DOM w programach Java i PL/SQL

Zaawansowane aplikacje WWW - laboratorium

Perl a XML. Narzędzia informatyczne w językoznawstwie. Generowanie danych XML - Przykład. Generowanie danych XML. Perl - Przetwarzanie XML

Programowanie w języku Java - Wyjątki, obsługa wyjątków, generowanie wyjątków

SAX i DOM wykorzystanie XML-a we własnych aplikacjach. Simple API for XML Parsing Document Object Model

Podstawy XML-a. Zaawansowane techniki programowania

JAVA I XML ZAGADNIENIA: DOM, SAX, JAXB, XMLDecoder i XMLEncoder, ANT.

Zdalne wywołanie metod - koncepcja. Oprogramowanie systemów równoległych i rozproszonych Wykład 7. Rodzaje obiektów. Odniesienie do obiektu

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Programowanie Obiektowe Ćwiczenie 4

Kurs programowania. Wykład 3. Wojciech Macyna. 22 marca 2019

Procesowanie dokumentów XML

Oprogramowanie systemów równoległych i rozproszonych Wykład 7

Wykład 8: Obsługa Wyjątków

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Wywoływanie metod zdalnych

Extensible Markup Language (XML) Wrocław, Java - technologie zaawansowane

JAVA W SUPER EXPRESOWEJ PIGUŁCE

KLASY, INTERFEJSY, ITP

XML i Java 1. XML Budowa dokumentu XML. Projektowanie systemów informatycznych

Modele dostępu do dokumentu XML. Implementacja modelu parser. SAX2 pakiet org.xml.sax. Działanie modelu SAX przykład

Wykład 7: Pakiety i Interfejsy

Języki i metody programowania Java INF302W Wykład 3 (część 1)

Obiektowe programowanie rozproszone Java RMI. Krzysztof Banaś Systemy rozproszone 1

Programowanie obiektowe

Programowanie obiektowe

Autor: dr inż. Zofia Kruczkiewicz, Programowanie aplikacji internetowych 1

Kurs programowania. Wstęp - wykład 0. Wojciech Macyna. 22 lutego 2016

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Wyjątki. Streszczenie Celem wykładu jest omówienie tematyki wyjątków w Javie. Czas wykładu 45 minut.

XML w.net. Dominik Baś nr alb Wrocław, 29 maja 2007

Multimedia JAVA. Historia

Wykład 2 Wybrane konstrukcje obiektowych języków programowania (1)

Klasy abstrakcyjne, interfejsy i polimorfizm

akademia androida Składowanie danych część VI

Wywoływanie metod zdalnych

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Wyjątki (exceptions)

Podstawy i języki programowania

Zad.30. Czy można utworzyć klasę, która implementuje oba interfejsy?

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Przetwarzanie dokumentów XML i zaawansowane techniki WWW Wykład 05

Klasy abstrakcyjne i interfejsy

Polimorfizm. dr Jarosław Skaruz

SAX2 pakiet org.xml.sax

libxml2 parser DOM dla C++ czwartek, 8 grudnia 11

Współbieżność i równoległość w środowiskach obiektowych. Krzysztof Banaś Obliczenia równoległe 1

Podstawy programowania obiektowego

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

Tablice i łańcuchy znakowe jako obiektowe typy danych. dr Jarosław Skaruz

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Throwable. Wyjatek_1(int x_) { x = x_; } int podaj_x()

Obiektowy model dokumentu. Katedra Mikroelektroniki i Technik Informatycznych

Rozdział 4 KLASY, OBIEKTY, METODY

Polimorfizm, metody wirtualne i klasy abstrakcyjne

Aplikacje RMI

XML i nowoczesne technologie zarządzania treścią 2007/08

Programowanie obiektowe

Programowanie obiektowe

Wykład 4: Klasy i Metody

Plan prezentacji. Przetwarzanie dokumentów XML JAXP SAX JAXP SAX DOM STAX XSLT. Przedmiot: XML i jego zastosowania. Dr inż. Stanisław Polak JAXB

Systemy Rozproszone - Ćwiczenie 6

Podejście obiektowe do budowy systemów rozproszonych

Remote Method Invocation 17 listopada Dariusz Wawrzyniak (IIPP) 1

Język JAVA podstawy. wykład 2, część 1. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Java: kilka brakujących szczegółów i uniwersalna nadklasa Object

Dokumentacja do API Javy.

DTD - encje ogólne i parametryczne, przestrzenie nazw

XML we własnych aplikacjach

Aplikacje RMI. Budowa aplikacji rozproszonych. Część 2.

WYJĄTKI. Jest ona jednak czasochłonna i prowadzi do duŝego zapotrzebowania na zasoby systemu.

Katalog książek cz. 2

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Programowanie obiektowe

Aplikacje RMI Lab4

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Wykład 2: Podstawy Języka

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Remote Method Invocation 17 listopada 2010

Java. Wykład. Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ

Wykład 3 Składnia języka C# (cz. 2)

Kurs programowania. Wykład 9. Wojciech Macyna. 28 kwiecień 2016

1 Wątki 1. 2 Tworzenie wątków 1. 3 Synchronizacja 3. 4 Dodatki 3. 5 Algorytmy sortowania 4

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

Biblioteki dzielone, XML i readline

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Wyjątki Monika Wrzosek (IM UG) Programowanie obiektowe 180 / 196

Ada-95. Dariusz Wawrzyniak

Wykład 4. Tablice. Pliki

Podejście obiektowe. Tablice obiektów Przykład 1 metody i atrybuty statyczne oraz niestatyczne

MATERIAŁY DO ZAJĘĆ I. Podstawowe pojęcia. Algorytm. Spis treści Przepis

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Obsługa błędów za pomocą wyjątków. Paweł Motofa (140746)

Java podstawy jęyka. Wykład 2. Klasy abstrakcyjne, Interfejsy, Klasy wewnętrzne, Anonimowe klasy wewnętrzne.

Diagramy klas. dr Jarosław Skaruz

Pakiety i interfejsy. Tomasz Borzyszkowski

Specyfikacja API Runtime BAS 3.0

JĘZYK PYTHON - NARZĘDZIE DLA KAŻDEGO NAUKOWCA. Marcin Lewandowski [ mlew@ippt.gov.pl ]

Transkrypt:

Plan Przetwarzanie dokumentów XML i zaawansowane techniki WWW Wykład 06 T. Romańczukiewicz Jagiellonian University 2009/2010

Plan Plan 1 SAX 2 Podsumowanie

Plan SAX Podsumowanie Przypomnienie Wstęp Obsługa błędów Kolejny przykład Kolejny prz 1 SAX Przypomnienie Wstęp Obsługa błędów Kolejny przykład Kolejny przykład 2 Podsumowanie

XML, poprawnie sformuowanie Sposoby opisu XML DTD XML Schema XPATH Sposoby prezentacji CSS XSLT DOM

DOM SAX Podsumowanie Przypomnienie Wstęp Obsługa błędów Kolejny przykład Kolejny prz DOM DOM W3C Document Object Model jest niezależnym od języka i platformy interfejsem pozwalajacym programom i skryptom na dostęp i zmiany w dokumentach XML. DOM i SAX SAX (ang. Simple API for XML czyli Proste API dla XML-a) interfejs programistyczny do sekwencyjnego parsowania dokumentów XML. Jest to jeden z mechanizmów, który pozwala odczytywać dane zapisane w dokumentach XML. Parser, który implementuje SAX, działa jako parser strumieniowy sterowany zdarzeniami. Przetwarzanie z użyciem SAX jest jednokierunkowe - wcześniej przetworzone dane nie moga być ponownie odczytane bez ponownego uruchomienia całej procedury. SAX został zaimplementowany w wielu językach obiektowych takich jak Java, C++, Visual Basic, Python czy Perl. Interfejs nie został jednak całkowicie zestandaryzowany i nawet pomiędzy różnymi kompilatorami C++ moga być różnice. korzystanie z modelu DOM wymaga wczytania całego dokumentu XML do pamięci i przechowywania go tam w postaci struktury drzewiastej o tym trzeba koniecznie pamiętać! należy uważać na DOM przy przetwarzaniu dużych ilości danych

W przeciwieństwie do interfejsu SAX, obiektowy model dokumentu wywodzi się z kręgów konsorcjum W3C. SAX to oprogramowanie będace własnościa publiczna. DOM jest samym w sobie standardem, tak jak XML. Model sekwencyjny(interfejs SAX) nie umożliwia uzyskania swobodnego dostępu do dokumentu XML. Informacje o dokumencie XML pobierane sa wtedy, kiedy robi to parser Kiedy pojawia się element 2., to nie można uzyskać dostępu do informacji w elemencie 4., ponieważ nie został on jeszcze przetworzony. Kiedy pojawi się element 4., to nie można powrócić do elementu 2.

Przetwarzanie XML-a przez SAX Parser, który implementuje SAX, działa jako parser strumieniowy sterowany zdarzeniami. Użytkownik określa szereg metod, które obsługuja zdarzenia pojawiajace się podczas przetwarzania danych. SAX rozpoznaje m.in. następujace elementy dokumentu XML: węzły tekstowe elementy instrukcje przetwarzania komentarze Zdarzenia wywoływane sa podczas napotkania któregokolwiek z powyższych elementów - dwukrotnie, na poczatku i na końcu. Atrybuty sa dostępne jako część danych przekazywanych do procedury obsługi danego zdarzenia. Przetwarzanie z użyciem SAX jest jednokierunkowe - wcześniej przetworzone dane nie moga być ponownie odczytane bez ponownego uruchomienia całej procedury.

Dostęp hierarchiczny SAX Podsumowanie Przypomnienie Wstęp Obsługa błędów Kolejny przykład Kolejny prz Dostęp do elementów poprzez SAX jest w dużym stopniu hierarchiczny i sekwencyjny. Uzyskujemy dostęp do krańcowego elementu węzła, potem przechodzimy z powrotem w górę drzewa i znów schodzimy do innego elementu na dole hierarchii. Nie ma przejrzystego odniesienia do poziomu hierarchii, na którym aktualnie się znajdujemy. Nie ma zaimplementowanego pojęcia elementu siostrzanego, następnego elementu na tym samym poziomie nie ma też możliwości sprawdzenia, które elementy sa zagnieżdżone w których. XSLT i XPath często musza korzystać z całego drzewa. Można to naturalnie wykorzystaćw DOM, w SAX praktycznie tego nie da sie zrobić. O tym czy korzystać z DOM czy SAX należy sie zdecydować w zależności od konkretnego zastosowania. DOM jest wygodniejszy w przypadku skomplikowanych struktur danych. W przypadku płytkich danych SAX działa o wiele szybciej i oszczędniej. StAX Istnieje rozwiazanie pośrednie pomiędzy modelem DOM i SAX: Metafora przetwarzania strumieniowego w StAX jest kursor, który reprezentuje pojedynczy punkt w całym dokumencie XML. Programista zawsze wie, gdzie kursor się znajduje, może na żadanie przesuwać ten kursor do przodu i pobierać informacje z parsera wedle własnego uznania. Jest to podejście podobne do tego używanego w modelu zdarzeń takim jak SAX, lecz z ta różnica, że informacje z parsera sa przesyłane tylko na żadanie, a nie jak w przypadku SAX, który przesyła je bez względu na to czy sa

SAX nie udostępnia domyślnego modelu danych tak jak robi to DOM. Trzeba samodzielnie stworzyć taki model danych np. (ksiażkę adresowa) do przechowywania danych z XML w programie Java. Należy również zaimplementować handler do przechwytywania zdarzeń zgłaszanych przez parser.

Listing 1: Przetwarzanie pliku XML 1 import java.io.ioexception; 2 import org.xml.sax.saxexception; 3 import org.xml.sax.xmlreader; 4 import org.apache.xerces.parsers.saxparser; 5 6 public class SAXParserDemo { 7 public void performdemo(string uri) { 8 System.out.println("Przetwarzanie pliku XML: " + uri + "\n\n"); 9 10 try { 11 XMLReader parser = new SAXParser(); 12 parser.parse(uri); 13 } catch (IOException e) { System.out.println("Blad przy wczytywaniu URI : " + e.getmessage()); } 14 catch (SAXException e) { System.out.println("Blad w przetwarzaniu: " + e. getmessage()); } 15 } 16 public static void main(string[] args) { 17 if (args.length!= 1) { 18 System.out.println("Uzycie: java SAXParserDemo [XML URI]"); 19 System.exit(0); 20 } 21 String uri = args[0]; 22 SAXParserDemo parserdemo = new SAXParserDemo(); 23 parserdemo.performdemo(uri); 24 } 25 }

W klasach SAX 1.0 zdefiniowano główny interfejs przetwarzajacy jako Parser i stad wiele zmiennych również odziedziczyło nazwę typu parser zamiast reader Kiedy parser jest już załadowany i gotowy do wykorzystania, można przekazać mu do przetworzenia dokument. Służy do tego metoda parse(), wchodzaca w skład klasy org.xml.sax.xmlreader. W parserze SAX musimy zarejestrować procedury obsługi (ang. handlers). Procedura obsługi to po prostu grupa wywołań wstecznych zdefiniowanych w ramach interfejsu SAX i umożliwiajacych wywoływanie kodu aplikacji w przypadku zajścia konkretnych zdarzeń w czasie przetwarzania dokumentu. Wywołania te będa następowały w czasie przetwarzania dokumentu, a nie po jego przetworzeniu. SAX umożliwia obsługę dokumentu sekwencyjnie, bez konieczności wczytywania go całego do pamięci. Procedury obsługi W interfejsie SAX 2.0 istnieja cztery podstawowe procedury obsługi: org.xml.sax.contenthandler obsługa standardowych zdarzeń zwiazanych z danymi dokumentu XML org.xml.sax.errorhandler obsługa błędów znalezionych w dokumencie org.xml.sax.dtdhandler obsługa DTD org.xml.sax.entityresolver służy do tłumaczenia encji zewnętrznych wstawionych do dokumentu XML Każdy z tych interfejsów może zostać zaimplementowany w klasach aplikacji wykonujacych specyficzne zadania. Klasy implementacyjne rejestrowane sa w parserze metodami set(...)handler().

Interfejs ContentHandler W interfejsie org.xml.sax.contenthandler zdefiniowano szereg istotnych metod cyklu przetwarzania, na które nasza aplikacja może reagować. Listing 2: setcontenthandler 1 public void performdemo(string uri) { 2 ContentHandler contenthandler = new MyContentHandler(); 3 try { 4 XMLReader parser = new SAXParser(); 5 parser.setcontenthandler(contenthandler); 6 parser.parse(uri); 7 } catch (IOException e) { System.out.println("Blad przy wczytywaniu URI: " + e.getmessage()); } 8 catch (SAXException e) { System.out.println("Blad w przetwarzaniu: " + e. getmessage()); } 9 }

Listing 3: class MyContentHandler 1 class MyContentHandler implements ContentHandler { 2 private Locator locator; 3 public void setdocumentlocator(locator locator) { } 4 public void startdocument() throws SAXException { } 5 public void enddocument() throws SAXException { } 6 public void processinginstruction(string target, String data) throws SAXException { } 7 public void startprefixmapping(string prefix, String uri) { } 8 9 public void endprefixmapping(string prefix) { } 10 11 public void startelement(string namespaceuri, String localname, String rawname, Attributes atts) 12 throws SAXException { } 13 14 public void endelement(string namespaceuri, String localname, String rawname) 15 throws SAXException { } 16 public void characters(char[] ch, int start, int end) 17 throws SAXException { } 18 public void ignorablewhitespace(char[] ch, int start, int end) 19 throws SAXException { } 20 public void skippedentity(string name) throws SAXException { } 21 }

Klasa org.xml.sax.locator udostępnia szereg metod takich jak getlinenumber() i getcolumnnumber(), zwracajacych bieżace miejsce w dokumencie XML. Klasy tej powinno się używać wyłacznie w zakresie implementacji ContentHandler startdocument() wywoływana jest przed wszelkimi innymi wywołaniami wstecznymi, również przed tymi znajdujacymi się w innych procedurach obsługi SAX enddocument() jest zawsze wywoływana jako ostatnia, również bez względu na procedurę obsługi. Obejmuje to także sytuacje, w których proces przetwarzania zostaje zatrzymany w wyniku napotkania błędów. 1 public void startdocument() throws SAXException 2 { System.out.println("Rozpoczyna sie przetwarzanie..."); } 3 4 public void enddocument() throws SAXException 5 { System.out.println("...Przetwarzanie skonczone."); } Jedyny wyjatek zgłaszany przez SAX to SAXException

Instrukcja przetwarzania 1 public void processinginstruction(string target, String data) throws SAXException 2 { System.out.println("PI: Obiekt docelowy:" + target + " i dane:" + data); } Uwaga: deklaracji XML to instrukcja przetwarzania udostępniajaca wersję, opcjonalne informacje o kodowaniu oraz o tym, czy dany dokument jest dokumentem samodzielnym: <?xml version="1.0"encoding="utf-8"standalone="yes"?> Instrukcja ta przeznaczona jest specjalnie dla parsera XML. Umożliwia zgłoszenie błędu (np. o nieobsługiwanej wersji) na samym poczatku przetwarzania. Ponieważ instrukcja ta obsługiwana jest tylko przez parser, nie powoduje wywołania processinginstruction(). Należy uważać, aby nie stworzyć kodu oczekujacego tej instrukcji lub informacji o wersji, ponieważ aplikacja nigdy nie otrzyma wywołania wstecznego do tej instrukcji przetwarzania.

Obsługa przestrzeni nazw. Odwzorowanie przedrostków (prefix mapping) to po prostu element, w którym za pomoca atrybutu xmlns deklarowana jest przestrzeń nazw. Wywołanie startprefixmapping(string prefix, String uri) otrzymuje przedrostek przestrzeni nazw oraz identyfikator URI skojarzony z tym przedrostkiem. Odwzorowanie uznawane jest za zamknięte, gdy zamknięty zostaje element deklarujacy to odwzorowanie. endprefixmapping(string prefix) oznacza napotkanie końca odwzorowania i pojawia się bezpośrednio po znaczniku zamykajacym elementu, w którym zadeklarowano odwzorowanie. 1 <glowny> 2 <element1> 3 <mojaprzestrzennazw:element2 xmlns:mojaprzestrzennazw="http://mojurl.pl "> 4 <mojaprzestrzennazw:element3>tu jakies dane</ mojaprzestrzennazw:element3> 5 </mojaprzestrzennazw:element2> 6 </element1> 7 </glowny>

Wywołania zwiazane z elementami startelement(string namespaceuri, String localname, String rawname, Attributes atts) informuje aplikację o elemencie XML i ewentualnych jego atrybutach. Parametry wywołania to nazwa elementu (w różnych postaciach) oraz egzemplarz klasy org.xml.sax.attributes (zawiera referencje do wszystkich atrybutów elementu i umożliwia przetwarzanie kolejnych atrybutów elementu w postaci podobnej do Vector). Oprócz możliwości odwołania się do atrybutu za pomoca indeksu, możliwe jest również odwołanie się poprzez nazwę. Metody pomocnicze, takie jak geturi(int index) i getlocalname(int index), dzięki którym można uzyskać dodatkowe informacje o przestrzeni nazw zwiazanej z danym atrybutem. Cały interfejs Attributes stanowi więc wszechstronne źródło danych o atrybutach elementu. Uwaga: Podczas iteracji po implementacji klasy Attributes atrybuty niekoniecznie będa pojawiały się w kolejności, w jakiej zostały przetworzone (czyli w takiej, w jakiej wpisano je do dokumentu). 1 public void startelement(string namespaceuri, String localname, String rawname, Attributes atts) 2 throws SAXException { 3 System.out.print("startElement: " + localname); 4 if (!namespaceuri.equals("")) 5 { System.out.println(" w przestrzeni nazw " + namespaceuri + " (" + rawname + ")"); } 6 else { System.out.println(" nie posiada skojarzonej przestrzeni nazw"); } 7 8 for (int i=0; i<atts.getlength(); i++) 9 System.out.println(" Atrybut: " + atts.getlocalname(i) + "=" + atts. getvalue(i)); 10 }

Dane elementu SAX Podsumowanie Przypomnienie Wstęp Obsługa błędów Kolejny przykład Kolejny prz Dane składaja się zazwyczaj z kolejnych elementów, danych tekstowych lub obu jednocześnie. Kiedy pojawiaja się kolejne elementy, następuja dla nich odpowiednie wywołania i rozpoczyna się proces pseudorekurencyjny elementy zagnieżdżone w elementach powoduja wywołania zagnieżdżone w wywołaniach. W pewnej chwili parser napotyka dane tekstowe. Informacje takie przeważnie sa wyświetlane lub służa do zbudowania odpowiedzi. W XML-u dane tekstowe w elementach przesyłane sa do aplikacji za pomoca wywołania characters(). Metoda ta udostępnia aplikacji tablicę znaków oraz indeksy poczatkowy i końcowy, które wskazuja, gdzie należy odczytać odpowiednie dane. Interfejs i standard SAX nie definiuja ściśle, jak korzystać z tego wywołania przy przetwarzaniu większych ilości danych tekstowych. Parser może zwrócić długi ciag danych w jednym wywołaniu lub rozbić dane na wiele wywołań. Dla danego elementu metoda ta może zostać wywołana zero razy (jeśli element nie zawiera danych tekstowych) albo jeden lub więcej razy. Wszysko zależy od konkretnego parsera. 1 public void characters(char[] ch, int start, int end) 2 throws SAXException { 3 String s = new String(ch, start, end); 4 System.out.println("znaki: " + s); 5 }

1 <macierzysty> 2 To jest 3 <potomny>zagniezdzony tekst</potomny> 4 dalszy tekst 5 </macierzysty> Efekt parsowania: 1 startelement: macierzysty nie posiada skojarzonej przestrzeni nazw. 2 znaki: To jest. 3 startelement: potomny nie posiada skojarzonej przestrzeni nazw. 4 znaki: zagniezdzony tekst. 5 endelement: potomny. 6 znaki: dalszy tekst. 7 endelement: macierzysty. SAX nie wybiega z przetwarzaniem naprzód, a wiec wynik jest dokładnie taki, jaki uzyskalibyśmy czytajac dokument XML sekwencyjnie, bez ludzkich przyzwyczajeń.

Można również dodać obsługę białych znaków: 1 public void ignorablewhitespace(char[] ch, int start, int end) 2 throws SAXException 3 { 4 String s = new String(ch, start, end); 5 System.out.println("ignorableWhitespace: [" + s + "]"); 6 } oraz pominiętych encji 1 public void skippedentity(string name) throws SAXException { 2 System.out.println("Pomijam encje " + name); 3 } Większość istniejacych parserów nie pomija encji, nawet jeśli nie sa to parsery sprawdzajace poprawność. Jeśli znajdziemy parser, który korzysta z powyższego wywołania, należy pamiętać, że przekazany parametr nie zawiera otwierajacego znaku & ani końcowego średnika.

Oprócz interfejsu ContentHandler, SAX udostępnia również interfejs ErrorHandler, służacy do obsługi sytuacji awaryjnych zaistniałych w czasie przetwarzania. Zdefiniowano w niej jedynie trzy wywołania wsteczne warning, error i fatalerror. Każda metoda otrzymuje informacje o błędzie lub ostrzeżeniu poprzez klasę SAXParseException. Obiekt ten zawiera numer wiersza, w którym wystapił bład, identyfikator URI przetwarzanego dokumentu oraz zwykłe informacje o błędzie, takie jak komunikat i dane ze śledzenia stosu. Każda metoda może zgłosić SAXException. Każda z procedur obsługi błędów otrzymuje wyjatki zwiazane z przetwarzaniem. Może to być ostrzeżenie, które nie powinno przerwać procesu przetwarzania, lub bład, który należy rozwiazać, aby to przetwarzanie mogło być kontynuowane. Jednak wywołanie takie może także wykonywać operacje wejścia-wyjścia lub inne, które moga spowodować zgłoszenie wyjatku - i wyjatek ten należy przekazać aż na sama górę, do aplikacji. Służy do tego właśnie wyjatek SAXException.

Listing 4: ErrorHandler.java cd. 1 import org.xml.sax.errorhandler; 2 import org.xml.sax.saxparseexception; 3 4 class MyErrorHandler implements ErrorHandler { 5 public void warning(saxparseexception exception) 6 throws SAXException { } 7 public void error(saxparseexception exception) 8 throws SAXException { } 9 public void fatalerror(saxparseexception exception) 10 throws SAXException { } 11 } 12 13 public class SAXParserDemo { 14 (...) 15 ContentHandler contenthandler = new MyContentHandler(); 16 ErrorHandler errorhandler = new MyErrorHandler(); 17 18 try { 19 XMLReader parser = new SAXParser(); 20 parser.setcontenthandler(contenthandler); 21 parser.seterrorhandler(errorhandler); 22 (...) 23 } 24 }

Ostrzeżenia: za każdym razem, gdy pojawi się ostrzeżenie (wynikajace ze specyfikacji XML 1.0), metoda ta wywoływana jest w zarejestrowanej procedurze obsługi błędów. Wszystkie sytuacje generujace ostrzeżenia zwiazane sa z definicjami DTD i poprawnościa składniowa dokumentu Błędy niekrytyczne występuja w czasie przetwarzania. Można je naprawić, ale stanowia pogwałcenie fragmentu specyfikacji XML, postrzegane sa jako błędy niekrytyczne. Procedura obsługi błędów powinna je przynajmniej odnotować w pliku dziennika Błędy krytyczne to te, które wymuszaja zatrzymanie działania parsera. Zazwyczaj wynikaja z niepoprawnego sformatowania dokumentu i ich pojawienie się oznacza, że albo dalsze przetwarzanie nie ma sensu, albo jest technicznie niemożliwe.

Ładowanie parsera SAX Podsumowanie Przypomnienie Wstęp Obsługa błędów Kolejny przykład Kolejny prz W pierwotnym przykładzie importowana była implementacja klasy XMLReader apacha: import org.apache.xerces.parsers.saxparser; Takiego kodu nie da się uruchomić, a nawet skompilować na platformie nie wykorzystujacej parsera Apache Xerces - kod nie jest przenośny Zaleca się stworzenie egzemplarza klasy o nazwie klasy pobranej z implementacji. 1 import org.xml.sax.helpers.xmlreaderfactory; 2 (...) 3 XMLReader parser = XMLReaderFactory.createXMLReader 4 (PropertiesReader().getInstance().getProperty("parserClass"));

Listing 5: AddressBook.xsl 1 <?xml version = "1.0"?> 2 <addressbook> 3 <person> 4 <lastname>romanczukiewicz</lastname> 5 <firstname>tomasz</firstname> 6 <company>wydzial FAIS, UJ</company> 7 <email>trom@th.if.uj.edu.pl</email> 8 </person> 9 </addressbook> Użycie SAX Stworzenie odpowiedniego modelu danych (klassy Person i AddressBook Stworzenie Parsera Stworzenie pocedur obsługi

Listing 6: AddressBook.java 1 import java.util.*; 2 public class AddressBook 3 { 4 List persons = new java.util.arraylist(); 5 public void addperson( Person p ) { persons.add( p ); } 6 public int getsize() { return persons.size(); } 7 public Person getperson( int i ) { return (Person)persons.get( i ); } 8 9 public String toxml(){ 10 StringBuffer sb = new StringBuffer(); 11 sb.append( "<?xml version=\"1.0\"?>\n" ); 12 sb.append( "<ADDRESSBOOK>\n\n" ); 13 for(int i=0; i<persons.size(); i++) { 14 sb.append( getperson(i).toxml() ); 15 sb.append( "\n" ); 16 } 17 sb.append( "</ADDRESSBOOK>" ); 18 return sb.tostring(); 19 } 20 } Ksiazka adresowa - lista osób (Person)

Listing 7: Person.java 1 public class Person 2 { 3 String fname, lname, company, email; 4 5 public String getcompany(){return company;} 6 public String getemail(){return email;} 7 public String getfirstname(){return fname;} 8 public String getlastname(){return lname;} 9 10 public void setlastname( String s ){lname = s;} 11 public void setfirstname( String s ){fname = s;} 12 public void setcompany( String s ){company = s;} 13 public void setemail( String s ){email = s;} 14 15 public String toxml(){ 16 StringBuffer sb = new StringBuffer(); 17 sb.append( "<PERSON>\n" ); 18 sb.append( "\t<lastname>"+lname+"</lastname>\n" ); 19 sb.append( "\t<firstname>"+fname+"</firstname>\n" ); 20 sb.append( "\t<company>"+company+"</company>\n" ); 21 sb.append( "\t<email>"+email+"</email>\n" ); 22 sb.append( "</PERSON>\n" ); 23 return sb.tostring(); 24 } 25 } / / end o f Person c l a s s Klasa Person zawiera informacje jakie sa zawarte w ksiazce adresowej.

Listing 8: SaxAddressBookHandler.java 1 import java.io.*; 2 import org.xml.sax.*; 3 import org.xml.sax.helpers.parserfactory; 4 import com.sun.xml.parser.resolver; 5 6 public class SaxAddressBookHandler extends HandlerBase{ 7 8 private AddressBook ab = new AddressBook(); 9 private Person p = null; / / temp Person r e f 10 private String currentelement = null; / / c u r r e n t e l e m e n t name 11 public AddressBook getaddressbook(){ return ab; } 12 public void startdocument() throws SAXException{ debugdisplay( "start doc" ); } 13 public void enddocument() throws SAXException{ debugdisplay( "end doc" ); } 14. 15. 16.

Listing 9: SaxAddressBookHandler.java cd. 1 public void startelement( String name, AttributeList atts ){ 2 3 debugdisplay( "<start elem:"+name+">"); 4 if( name.equalsignorecase("lastname") ) 5 { currentelement = "LASTNAME"; } 6 else if( name.equalsignorecase("firstname") ) 7 { currentelement = "FIRSTNAME"; } 8 else if( name.equalsignorecase("company") ) 9 { currentelement = "COMPANY"; } 10 else if( name.equalsignorecase("email") ) 11 { currentelement = "EMAIL"; } 12 else if( name.equalsignorecase("person") ) 13 { p = new Person(); } 14 } 15 16 public void endelement( String name ){debugdisplay( "</"+name+">" ); 17 if( name.equalsignorecase("person") ) { 18 ab.addperson( p ); 19 p = null; 20 } 21 } Po napotkaniu odpowiedniego elementu ustawiamy zmienna currentelement Jeśli danym elementem jest Person to tworzymy nowy obiekt klasy Person, który zostanie dodany do ksiażki adresowej po napotkaniu końca elementu Person.

Listing 10: SaxAddressBookHandler.java cd. 1 public void characters( char ch[], int start, int length ){ 2 String value = new String( ch, start, length ); 3 if(!value.trim().equals("")) { 4 if( currentelement.equalsignorecase("firstname") ) 5 { p.setfirstname( value ); } 6 else if( currentelement.equalsignorecase("lastname") ) 7 { p.setlastname( value ); } 8 else if( currentelement.equalsignorecase("company") ) 9 { p.setcompany( value ); } 10 else if( currentelement.equalsignorecase("email") ) 11 { p.setemail( value ); } 12 } Zawartość tekstowa z dokumentu XML przepisujemy do odpowiedniej zmiennej obektu Person, w zależności od wartości zmiennej currentelement

Sprawdzanie poprawności W interfejsie SAX 2.0 zdefiniowano standardowy mechanizm do ustawiania istotnych właściwości i cech parsera. Umożliwia on dodawanie nowych właściwości i cech w miarę przyjmowania ich przez W3C, bez konieczności stosowania własnych metod lub rozszerzeń. Listing 11: Parsowanie 1 try { 2 XMLReader parser = 3 XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser"); 4 parser.setcontenthandler(contenthandler); 5 parser.seterrorhandler(errorhandler); 6 parser.setfeature("http://xml.org/sax/features/validation", true); 7 parser.parse(uri); 8 } catch (IOException e) 9 { System.out.println("Blad przy wczytywaniu URI: " + e.getmessage()); } 10 catch (SAXException e) 11 { System.out.println("Blad w przetwarzaniu: " + e.getmessage()); 12 }

Metody do obsługi właściwości i cech parsera parser.setproperty([uri wlasciwosci], [Parametr obiektu]); parser.setfeature([uri cechy], true); parser.getproperty([uri wlasciwosci]); parser.getfeature([uri cechy]) W każdej z powyższych metod identyfikatorem ID określonej właściwości lub cechy jest identyfikator URI Producent parsera XML powinien udostępnić dodatkowa dokumentację informujaca o obsługiwanych cechach i właściwościach. Dobry parser umożliwi korzystanie z nich bez posiadania połaczenia z siecia. W tym sensie identyfikatory URI można postrzegać jako proste stałe, które akurat maja format URI.

Plan SAX Podsumowanie 1 SAX 2 Podsumowanie

SAX Podsumowanie Interfejs programistyczny do sekwencyjnego parsowania dokumentów XML. Działa jako parser strumieniowy sterowany zdarzeniami. Przetwarzanie z użyciem SAX jest jednokierunkowe SAX został zaimplementowany w wielu językach obiektowych W przeciwieństwie do DOMa nie wymaga dużych zasobów systemowych i zazwyczaj działa dużo szybciej. Nie można jednak łatwo poruszać się po strukturze dokumentu. Programista definiu metody przechwytywania zdarzeń takich zgłaszanych przez parser takich jak poczatek/koniec elementu, instrukcje przetwarzania, przestrzenie nazw Umożliwia kontrolę wyjatków Można stosowac do sprawdzania poprawności dokumentów