310 likes | 447 Views
Technologie Internetu wykład 11: Interfejsy programistyczne dla przetwarzania XML Piotr Habela Polsko-Japońska Wyższa Szkoła Technik Komputerowych. W poprzednim odcinku….
E N D
Technologie Internetu wykład 11:Interfejsy programistyczne dla przetwarzania XML Piotr Habela Polsko-Japońska Wyższa Szkoła Technik Komputerowych 1
W poprzednim odcinku… • Język XSL w swojej części dotyczącej transformacji (XSLT) stanowi środek dla deklaratywnego określania sposobu przekształcania dokumentów. • Uruchamianie konkretnych szablonów (przez podanie ich nazwy) oraz przekazywanie doń parametrów wnoszą do XSLT cechy programowania proceduralnego. • Zasadnicze scenariusze przekształceń XSLT: • Przebudowa struktury dokumentu XML; • Generowanie HTML w oparciu o dane z pliku XML; • Formatowanie danych XML do postaci XSL-FO; • Przetwarzanie jednego arkusza XSLT w inny (np. celem personalizacji sposobu wyświetlania); • Tworzenie zwykłego tekstu jako dokumentu wyjściowego. 2
Plan wykładu • Document Object Model (DOM): dokument XML jako drzewo węzłów; • Simple API for XML (SAX): dostęp strumieniowy oparty o zdarzenia; • Java API for XML Processing (JAXP); • Java Architecture for XML Binding (JAXB); • JDOM i inne interfejsy. 3
Document Object Model (DOM) • Standard manipulacji dokumentami XML (specyfikacja W3C). Interfejs programistyczny do dokumentów HTML i XML. • Hierarchia dokumentu zostaje odwzorowana w pamięci komputera w postaci drzewa obiektów. • Możliwość nawigowania w dokumencie, modyfikowania go oraz tworzenia nowych dokumentów w pamięci. • Specyfikacja zaprojektowana jako niezależna od konkretnego języka programowania i platformy (definicje interfejsów w Java, ECMAScript i IDL). • Zwykle implementowany w oparciu o SAX (zob. dalej). • Specyfikacja złożona z kilku części. M.in.: Core (niskopoziomowy zbiór interfejsów mogących reprezentować każdy ustrukturalizowany dokument), HTML (interfejsy wyższego poziomu wprowadzone dla poprawienia wygody dostępu), XPath (wykorzystanie XPath w przetwarzaniu dokumentu). 4
DOM – rozwój specyfikacji • DOM Level 1: • Core – obiekty reprezentujące strukturę dokumentu; • HTML – dostęp do dokumentów HTML; • DOM Level 2: • Poprawiona specyfikacja części Core; • Events – reakcje systemu na zdarzenia użytkownika; • Style – manipulacja arkuszami stylów; • Views – widoki drzewa dokumentu (po zastosowaniu stylów CSS); • Traversal & Range – sposoby nawigowania; • DOM Level 3 (obecnie jako „Working draft”): • Poprawiona specyfikacja Core oraz Events; • modele zawartości (DTD, Schemas) wraz z walidacją dokumentu; • ładowanie i zapisywanie plików; • XPath – dostęp do zawartości dokumentu za pomocą wyrażeń XPath. 5
Struktura dokumentu DOM • DocumentElement: wierzchołek drzewa dokumentu; • Node: każdy z węzłów (w tym elementy); • Element a węzeł: element to jeden z występujących w dokumencie DOM rodzajów węzłów (m.in. węzły tekstowe, atrybutowe). • Węzły elementowe: zwykle zawierają węzły potomne: elementowe, tekstowe lub obu rodzajów. • Węzły atrybutowe: informacja podległa konkretnemu węzłowi elementowemu. Nie są określane jako potomkowie. • Węzeł dokumentu: rodzic dla wszystkich pozostałych węzłów. • CData: odpowiada sekcji znakowej, zawierającej zawartość nie przeznaczoną do przetwarzania; • Comment: (komentarz); ProcessingInstruction (instr. przetwarzania); • DocumentFragment: stosowany jako węzeł roboczy przy budowaniu lub rekonstruowaniu dokumentu XML. • Ponadto: Entity, EntityReference, Notation. 6
Najważniejsze interfejsy DOM (1) • DOMImplementation : • Umożliwia: sprawdzenie, czy dana funkcjonalność jest zaimplementowana, tworzenie nowej instancji dokumentu; tworzenie nowego typu dokumentu. • Document : • Udostępnia korzeń drzewa. • Określa: typ dokumentu, implementację DOM oraz element-korzeń. • Umożliwia : tworzenie elementu, atrybutu, węzła tekstowego, komentarza, sekcji znakowej, instrukcji przetwarzania, referencji do encji zewnętrznej ; tworzenie fragmentu dokumentu (zob. dalej) oraz wyszukiwanie elementów wg nazwy znacznika, według nazwy węzła oraz importowanie węzła do aktualnej lokalizacji. • W wersji 2 uwzględniono tworzenie elementów i atrybutów oraz wyszukiwanie elementów, z uwzględnieniem przestrzeni nazw. • W wersji 3 pojawiły się metody do odczytu i ustawienia atrybutów deklaracji XML, tj. version, encoding, standalone. 7
Najważniejsze interfejsy DOM (2) • DocumentFragment, Node: • Udostępnia następujące metody: insertBefore, replaceChild, removeChild, appendChild, hasChildNodes, cloneNode, normalize. • (od w. 2) rozszerzenia uwzględniające Namespaces; atrybuty namespaceURI, prefix, localName. • właściwości „tylko do odczytu”: nodeName, nodeValue (także aktualizacja), nodeType, parentNode, childNodes, firstChild, lastChild, previousSibling, nextSibling, attributes, ownerDocument. • Właściwość „nodeType” (typu całkowitoliczbowego), określa, z jakiego rodzaju węzłem mamy do czynienia. Określono też nazwane stałe dla wygodniejszej identyfikacji tego kodu rodzaju węzła, np. ELEMENT_NODE, TEXT_NODE. • Porównywanie węzłów (od wersji 3) : tożsamość : isSameNode(Node), równość: isEqualNode(Node), określenie stopnia pokrewieństwa w strukturze: compareTreePosition(Node) 8
Najważniejsze interfejsy DOM (3) • NodeList: • określa długość listy, umożliwia pobranie n-tego węzła; • Element: • Szczególny rodzaj węzła (Node). • Dostęp do atrybutów elementu: odczyt, usunięcie, modyfikacja, dodanie. • Wyszukiwanie podelementów. • Attr: • Określa nazwę atrybutu, wartość (odczyt i modyfikacja), element-właściciela, oraz czy atrybut został wyspecyfikowany czy też jest to wartość domyślna z definicji dokumentu. • CharacterData (abstrakcyjny): • Występuje jako: Comment, Text lub CDATASection • Udostępnia: zawartość tekstową, długość zawartości, operacje do modyfikacji i pobierania. 9
Moduł DOM Traversal • Służy uproszczeniu poruszania się po drzewie dokumentu DOM. • Złożony z 4 interfejsów: • DocumentTraversal służy wytworzeniu obiektu do nawigowania, będącego wystąpieniem jednego z dwóch interfejsów: • NodeIterator (szybszy) umożliwia jedynie poruszanie się w przód i wstecz wzdłuż płaskiej listy węzłów. • TreeWalker z kolei uwzględnia hierarchiczny model elementu. • NodeFilter. Służy określaniu, jakie węzły będą brane pod uwagę przy poruszaniu się po drzewie za pomocą którejś z powyższych metod. • Ponieważ wszystko to są interfejsy, należy ustalić, która z klas w dostępnym nam parserze implementuje DocumentTraversal. Zwykle jest to ta sama klasa, która implementuje org.w3c.dom.Document. 10
Użycie DOM Traversal • Interfejs NodeFilter należy zaimplementować celem wyselekcjonowania interesujących nas węzłów. Jego metoda acceptNode przyjmuje jako parametr testowany węzeł, zaś zwraca jako rezultat liczbę typu short, oznaczającą dyspozycję przyjęcia lub ominięcia testowanego węzła. • W wypadku zarówno NodeIterator jaki i TreeWalker, tworzenie ich obiektów wymaga następujących parametrów: • węzeł startowy (korzeń przeszukiwania); • rodzaje węzłów do przeszukania; • obiekt NodeFilter; • czy rozwijać referencje do encji? • Dobór optymalnego stylu nawigacji wraz z możliwością definiowania filtra znacznie ułatwiają selekcję szukanych węzłów. 11
Moduł DOM Range • Podobnie jak Traversal, dostarcza środków wyższego poziomu dla selekcjonowania zawartości dokumentu. • Jak wskazuje nazwa, wyznaczane są ciągłe zakresy w ramach dokumentu. Są one specyfikowane poprzez podanie węzła początkowego oraz przesunięcia (offset) w tym węźle oraz analogicznych danych dla węzła końcowego. • Przesunięcie (offset) oznacza (zależnie od rodzaju węzła) liczbę węzłów potomnych lub liczbę znaków (interpretacja zależna od sposobu kodowania). • Selekcję taką można sobie wyobrazić jako podobną do podświetlenia fragmentu tekstu w edytorze. Jednakże nie jest możliwe zbudowanie zakresu, który rozpoczynałby się lub kończył wewnątrz tagu elementu ani wewnątrz nazwy encji lub odnośnika. • Z drugiej zaś strony istnieje pojęcie częściowej selekcji danego węzła, jeśli dokładnie jeden z punktów wyznaczających zakres (boundary-points) znajduje się w jego wnętrzu. 12
Funkcjonalność modułu DOM Range • Funkcjonalność dla selekcji obejmuje: • wskazanie punktów poprzez węzły i przesunięcia w ich ramach; • wybranie węzła; • wybranie zawartości węzła; • określenie punktu względem danego węzła (przed lub za). • Pozostała funkcjonalność to m.in.: • usuwanie lub ekstrakcja (celem przemieszczenia) zakresu (elementy częściowo wyselekcjonowane pozostają w swoich pierwotnych miejscach, uszczuplone jedynie o wyselekcjonowaną zawartość); • porównywanie pozycji dwóch zakresów; • wstawianie węzła w wytyczone miejsce; • wstawianie węzła otaczającego dany zakres (generowany jest wyjątek, jeżeli zakres częściowo selekcjonuje jakiś nietekstowy węzeł). 13
SAX: Simple API for XML • Projektowany dla Javy (org.xml.sax, org.xml.sax.helpers); później także inne języki jak Python czy C++. • Określany jako interfejs „zdarzeniowy”: zdarzeniem jest napotkanie znaczników otwierających, zamykających, atrybutów itd. Umożliwia reagowanie na wybrane zdarzenia. • Przetwarzanie strumieniowe (jeden kierunek przetwarzania) => motywowane sprawnością działania w wypadku dużych dokumentów. • Wersja 2 (SAX2): wspierane przestrzenie nazwowe. • Projektowanie procesora SAX: określenie odpowiedzi na określone zdarzenia przetwarzania. 14
Zdarzenia w parserze SAX • Typowe zdarzenia dla minimalnego dokumentu XML: • początek dokumentu; • koniec dokumentu; • początek elementu; • koniec elementu; • odebrany tekst: przejście do następnej linii; inny znak biały; • odebrany tekst: np. zawartość tekstowa elementu; • Scenariusz przetwarzania: • ustalenie sposobów obsługi interesujących nas zdarzeń (implementacja metod obsługujących odpowiednie zdarzenia); • wywołanie metody parse(…) interfejsu XMLReader; • XMLFilter stanowi rozszerzenie XMLReader, pozwalające na budowanie łańcuchów kolejno stosowanych filtrów: umożliwia to dekompozycję złożonego przetwarzania. 15
Implementacja parsera SAX • Klasa SAXParserFactory jest używana do utworzenia obiektu SAXParser. • Ten ostatni zawiera w sobie obiekt SAXReader, do którego można podłączyć cztery obiekty – niejako „wtyczki” określające sposób przetwarzania: • ContentHandler: Najważniejsze metody startDocument, endDocument, startElement, endElement wołane przy napotkaniu odpowednich znaczników w przebiegu przez dokument. Zwykle są implementowane przez aplikację. Ponadto metody characters i processingInstruction – analogicznie, wołane po napotkaniu takowych bytów w przetwarzanym dokumencie. • ErrorHandler: Metody error, fatalError i warning wołane przy błędach parsowania. Domyślnie: wyjątki przy fatal errors, ignorowanie pozostałych. Może zaistnieć konieczność zmodyfikowania tego zachowania. • DTDHandler: Metody związane z przetwarzaniem DTD dotyczącym obsługi encji nieprzetwarzanych i specyfikacji ich notacji. • EntityResolver: Deklaruje metodę resolveEntity wołaną przy konieczności odszukania encji zewnętrznej, do której odwołanie napotkano w dokumencie. 16
DOM a SAX - podsumowanie • Interfejs DOM: • Odtwarza strukturę dokumentu w pamięci; • Umożliwia modyfikację dokumentu; • Pozwala na swobodny dostęp i nawigowanie w dowolnym kierunku; • Znaczne wymagania odnośnie zasobów: efektywny dla niewielkich dokumentów. • Interfejs SAX: • Nie pozwala na modyfikację struktury dokumentu; • Przetwarzanie strumieniowe zapewnia sprawność nawet dla dużych dokumentów; • Dostęp do dokumentu za pomocą tego interfejsu uchodzi za trudniejszy. 17
Java API for XML Processing (JAXP) • Wspólny standardowy interfejs tworzący podstawę dla wykorzystania interfejsów SAX, DOM oraz XSLT z poziomu języka Java, zapewniając niezależność wykorzystującego je kodu od konkretnych implementacji. • Podstawowe interfejsy zawarte w pakiecie javax.xml.parsers. Pozwalają na podłączania dowolnych zgodnych parserów. • W zakresie interfejsów SAX i DOM udostępnia fabryki obiektów realizujących oba te rodzaje przetwarzania. • W zakresie wsparcia XSLT, JAXP dostarcza interfejsów zdefiniowanych w pakiecie javax.xml.transform. • Klasa TransformerFactory tworzy obiekt Transformer przyjmujący plik źródłowy oraz wytyczne (w postaci pliku deklaracji XSLT) celem wygenerowania dokumentu wynikowego. • Poza dokonywaniem „złożeń” dokumentu źródłowego z odpowiednim arkuszem XSLT, możliwe jest również kierowanie transformacją poprzez dostarczanie wartości parametrów XSLT. 18
JAXP i DOM: podstawowe kroki • Tworzymy obiekt klasy DocumentBuilderFactory. Można dlań określić: • setValidating: czy przetwarzany XML będzie walidowany zgodnie z określonym dlań DTD lub schematem; • setCoalescing: Czy sekcje CDATA mają być przekształcane na tekst i zlewane z otaczającym je tekstem (false). • setExpandEntityReferences: Czy zewnętrzne encje będą odczytywane i wstawiane do dokumentu (true). • setIgnoringcomments: Czy komentarze będą ignorowane (false). • setIgnoringElementContentWhitespace: Czy znaki białe wewnątrz elementów mają być ignorowanie (false). • setNamespaceAware: Czy informacja o przestrzeniach nazwowych ma być brana pod uwagę (false). • Tworzymy zeń obiekt klasy DocumentBuilder: • posiada on metodę parse (mogącą pobierać jako parametr m.in. plik dyskowy, strumień wejściowy lub URI), zwracającą obiekt o interfejsie Document. 19
JAXP i DOM: podstawowe kroki • Odwołanie do obiektu Document: • umożliwia pobranie elementu-korzenia (jako obiektu klasy Element) lub wyszukiwanie określonych podelmentów; • Manipulacja zawartością: • Dostęp do elementów – obiekt Element; • Dostęp do węzłów innego rodzaju (klasa Node). • Sposoby pobierania węzłów: • Iteracja po węzłach potomnych: metody getFirstChild oraz getNextSibling • Wyszukanie potomków danego typu: metoda getElementsByTagName("nazwa") i przeglądanie zwróconej listy. • Dostęp do atrybutów: • Metoda getAttributes() na przetwarzanym węźle elementu; • Metody getNodeName() i getNodeValue() dla zwróconych atr. 20
DOM – operacje modyfikujące (1) • W węzłach o odpowiednim typie (tj. Attr, CDATASection, Comment, ProcessingInstruction, Text) można modyfikować wartość operacją setNodeValue(wartość) • Dołączanie nowego węzła może przebiegać następująco: • Stworzenie węzła: operacje createTextNode, createElement, createComment i odpowiednie inne, wywoływane na obiekcie typu Document. • Umieszczenie węzła w strukturze: na obiekcie węzła-rodzica wołamy metodę appendChild(nowyWęzeł) celem dołączenia go jako ostatniego dziecka, albo insertBefore(nowyWęzeł, węzełSąsiedni) – celem umieszczenia go wcześniej. • Usuwanie węzła: operacja removeChild(usuwanyWęzeł) wołana na obiekcie węzła-rodzica. Operacja zwraca referencję do obiektu węzła, więc może posłużyć do przemieszczania węzła (wstawienie w inne miejsce j.w.). 21
DOM – operacje modyfikujące (2) • Można również zastąpić wybrany węzeł, wywołując dla rodzica operację replaceChild(poprzedni, nowy). • Modyfikacja atrybutów: • Nowe węzły atrybutowe tworzymy operacją obiektu Document: doc.createAttribute(nazwaAtrybutu); • Dodawanie atrybutu – operacja setAttributeNode(węzełAtrybutu), wołana na docelowym elemencie (tzn. na obiekcie węzła elementu); • Alternatywnie (krócej): operacja setAttribute(nazwaAtrybutu, wartośćAtrybutu) wołana na elemencie. • Usuwanie atrybutu: operacja removeAttribute(nazwaAtrybutu). 22
DOM – zapis modyfikacji • Zapis oparty na środkach dostępu do plików oferowanych przez API Javy (pakiet java.io): użycie klas File oraz FileWriter: • Zapis samego drzewa dokumentu można zrealizować w oparciu o metodę toString() węzłu korzenia. • Z kolei chcąc zapisać w pliku deklarację XML i definicję DTD, musimy je skonstruować osobno. Przepisując dokument możemy odzyskać odwołanie do zewnętrznego DTD (tu – w postaci id systemowego) za pomocą operacji: naszDokument.getDoctype().getSystemId(); • Inne możliwości przekazania dokumentu wynikowego obejmują: wyjście strumieniowe (np. do parsera SAX), transformacje XSL czy też komunikat SOAP. 23
Java Architecture for XML Binding (JAXB) • Reprezentuje inne podejście do przetwarzania XML, zaliczane do tzw. wiązań XML. • JAXB powstała w ramach Java Community Process (JSR-031)i jest rozprowadzana m.in. w ramach pakietu Java Web Services Developer Pack. • Odpowiednie klasy Javy generowane (przez narzędzie zwane „kompilatorem wiązania”) są z definicji XML Schema. Są zwane „klasami zawartości” (content classes). Z uwagi na nieregularność DTD, jego ograniczenia (w tym brak wsparcia dla przestrzeni nazwowych), zrezygnowano z jego wspierania na rzecz XML Schema. • Przekształcenie pomiędzy zawartością XML a odpowiadającymi jej strukturami obiektów Javy i odwrotnie są określane odpowiednio jako unmarshalling i marshalling.Ta reprezentacja za pomocą obiektów Javy może być przedmiotem przeglądania, aktualizowania i walidacji. 24
JAXB – zasada działania • Podobnie jak w DOM, struktura dokumentu jest wczytywana do pamięci. Jednakże z uwagi na to, że wygenerowane klasy są wyspecjalizowane (a nie generyczne jak w wypadku DOM), mamy do czynienia ze strukturą oszczędniejszą w sensie zasobów i prostszą w obsłudze. • Odwzorowanie definicji schematu dokumentu na klasy Javy przypomina swym charakterem kompilację definicji IDL standardu CORBA, tworzącą tzw. pieńki i szkielety. • Nie wszystkie zadeklarowane ograniczenia wartości zapisane w XML Schema przekładają się na ograniczenia typów argumentów reprezentujących je w Javie operacji. Jednakże poprawność przetwarzanej struktury może być kontrolowana dzięki istniejącemu w JAXB mechanizmowi walidacji. Walidacja może być dokonywana przy wyczytywaniu XML oraz na żądanie. 25
JAXB – scenariusz użycia Dysponując definicją XML Schema można przystąpić do konstruowania aplikacji: • Wygenerowanie kodu źródłowego Javy z XML Schema za pomocą kompilatora wiązania. • Kompilacja wygenerowanego kodu. • Stworzenie aplikacji korzystającej z wygenerowanych klas zawartości: • Utworzenie struktury dokumentu XML zgodnej ze źródłowym schematem poprzez jej wczytanie w postaci kodu XML lub poprzez instancjonowanie wygenerowanych klas. • Odczyt i ewentualna manipulacja danych. • Ewentualna walidacja modyfikacji. • Zapisanie struktury do dokumentu XML. 26
JAXB – składniki technologii • Dokument XML Schema: określa budowę przetwarzanego dokumentu XML; źródło danych dla kompilatora wiązania. • Deklaracje wiązania: precyzują sposób konstruowania nazw w obiektach Javy (w tym nazw docelowych pakietów). Mogą wystąpić jako adnotacje w schemacie źródłowym albo w osobnym pliku. • Kompilator wiązania: tworzy kod klas Javy na podstawie źródłowego XML Schema. • Implementacja Binding Framework: Odczyt, zapis, walidacja. • Klasy zawartości: wygenerowane ze schematu; reprezentują zawartość dokumentu. • Aplikacja Javy: korzysta z binding framework i z klas zawartości celem przetwarzania określonego XML. • Wejściowe i wyjściowe dokumenty XML . 27
JAXB – składniki technologii Źródło: The Java™Architecture for XML Binding (JAXB) User’s Guide - Scott Fordin 28
DOM a Java • Document Object Model powstał jako specyfikacja niezależna od konkretnego jezyka programowania i zapewniająca dostęp do kompletnej zawartości dokumentu. • Z puktu widzenia wykorzystania w Javie posiada on pewne wady: • Znaczna konsumpcja zasobów: szczegółowa reprezentacja dokumentu jest w całości odtwarzania w pamięci. • Brak wykorzystania udogodnień specyficznych dla Javy, jak przeciążanie, Collection Framework. • Wobec tego podjęto prace nad interfejsami dla Javy, które za cenę genryczności mogłyby osiągnąć lepszą wygodę wykorzystania i mniejszą konsumpcję zasobów, jednak bardziej elastycznymi niż wymagająca statycznej wiedzy o schemacie JAXB. 29
JDOM: http://www.jdom.org • Narzędzie udostępniające zaprojektowany dla Javy model dokumentu XML. Jak sugeruje nazwa, inspirowany DOM; stanowi rozwiązanie alternatywne, łatwiejsze w użyciu, lecz nieprzenośne na inne języki programowania. • Rozwijane jako Java Community Process (JSR 102). • Możliwości integracji z DOM i SAX: zarówno wejście jak i wyjście przy przetwarzaniu z użyciem JDOM może przybrać postać: plików XML, drzew DOM lub zdarzeń SAX. • Istnieje możliwość wykorzystania XSLT i XPath do struktur JDOM. • Cecha szczególna: API JDOM jest oparte na klasach konkretnych Javy, nie zaś na interfejsach. Zapewnia to prostotę i zwięzłość (używamy konstruktorów zamiast pośrednictwa „fabryk”) kosztem elastyczności implementacji. 30
Inne API • DOM4J http://www.dom4j.org : • Kolejny projekt typu open-source. API oparte na interfejsach. Może to być przewagą w wypadku konieczności dostosowania implementacji do konkretnych potrzeb (np. do bardzo dużych zbiorów XML). • Korzysta z parsera SAX. • Podobna motywacja: prostsze i lżejsze od DOM API, stworzone dla języka Java. • JAXM (Java API for XML Messaging): • Wymiana asynchronicznych komunikatów XML pomiędzy aplikacjami. • JAX-RPC(Java API for XML-based Remote ProcessCommunications): • Wymiana synchronicznych komunikatów pomiędzy aplikacjami. • JAXR(Java API for XML Registries): • Publikowanie i odszukiwanie informacji o usługach Webu. 31