====== Laboratorium TIiM, XML ====== XML i JSON są najczęściej wykorzystywanymi formatami do wymiany danych pomiędzy klientem a serwerem w aplikacjach AJAX. XML stanowi również najczęściej wykorzystywany format pobierania danych z zewnętrznych serwisów, udostępniających odpowiednie interfejsy programistyczne (API). Do serwisów takich należą źródła bieżących wiadomości (news), serwisy pogodowe czy serwisy udostępniające bieżące wyniki rozgrywek sportowych. Wykorzystanie XML pozwala na automatyczne pobieranie tych danych w swojej aplikacji, a także (dzięki DTD lub XML Schema) na wersyfikację ich poprawności. ===== Ćwiczenia ===== Google udostępnia "nieoficjalne" API z prognozą pogody dla wybranej lokalizacji. API zwraca dane w formacie XML, znajduje się pod adresem http://www.google.com/ig/api i przyjmuje parametry: * ''weather'' - zawierający nazwę lokalizacji (np. ''Kraków''), * (opcjonalnie) ''hl'' - określający wersję językową (np. ''pl''). Aby pobrać pogodę dla Krakowa z opisami w języku polskim skorzystamy więc z adresu: http://www.google.com/ig/api?weather=Krakow&hl=pl ==== Ćwiczenie: XML i CSS ==== Napisz aplikację w PHP, która pobierze dokument XML opisujący pogodę dla danego regionu np. Kraków oraz zaprogramuj wizualizację tego dokumentu w przeglądarce, tak aby wyświetlane były informacje o: * lokalizacji, * aktualnej: temperaturze, wilgotności, wietrze, * prognozowanej: temperaturze, wilgotności, wietrze. Do wizualizacji wykorzystaj CSS. Ponieważ dokument opisujący pogodę nie posiada znaczników przypisujących mu CSS należy taki znacznik dynamicznie dodać. Skrpypt powinien zatem: - pobrać dane pogodowe w formacie XML, - dodać odpowiedni element określający CSS - zwrócić tak zmodyfikowany dokument. Uwaga: należy zwrócić uwagę na właściwy typ dokumentu zwracanego przez skrypt tj: ''text/xml'' oraz kodowanie znaków diakrytycznych zgodne z kodowaniem danych źródłowych. Ponizeważ dokument XML zawiera elementy w których dane przekazywane są z wykorzystaniem atrybutów bardzo przydatne będą selektory '':before'' oraz '':after'' oraz własność ''content''. Np. aby wyświetlić zawartość atrybutu ''data'' elementu ''condition'' należy użycć konstrukcji CSS: condition:after { content: attr(data); } ==== Ćwiczenie: XML i JS ==== Chcemy zbudować dokument/aplikację XHTML, który będzie zawierać informacje o pogodzie. Teoretycznie, nasza aplikacja mogłaby pobierać ten XML bezpośrednio z pogodowego API Goole (z wykorzystaniem AJAX), ale nie pozwala na to [[http://en.wikipedia.org/wiki/Same_origin_policy|same origin policy]]. Należy więc napisać bardzo prosty skrypt PHP, który pobierze XML z serwera i zwróci go bez żadnych zmian klientowi. Zadania: - Stwórz szkielet HTML, zawierający: * okienko tekstowe do wpisywania lokalizacji, * przycisk wykonujący zapytanie o pogodę, * elementy HTML (jednoznacznie identyfikowalne), w których będziemy umieszczać: * datę, której dotyczy prognoza (''forecast_information > forecast_date.data'') * pełną nazwę zidentyfikowanej lokalizacji (''forecast_information > city.data'') * 1 blok dla pogody aktualnej (''current_conditions''), zawierający: * opis pogody (''condition.data''), * temperaturę w st. C (''temp_c.data''), * wilgtotność (''humidity.data''), * element ''img'' na ikonkę pogody (gdzie ''src'' to ''icon.data''), * wiatr (''wind_condition.data''). * 2 dla kolejnych dni (kolejne elementy ''forecast_conditions''), każdy zawierający: * dzień tygodnia (''day_of_week > data''), * temperaturę minimalną (''low.data''), * temperaturę maksymalną (''high.data''), * opis pogody (''condition.data''), * element ''img'' na ikonkę pogody (gdzie ''src'' to ''icon.data''), - Napisz prosty skrypt PHP, przyjmujący jeden parametr GET (lokalizacja), pobierający XML z API Google i przekazujący bez zmian na wyjście. Dane polskojęzyczne przychodzą w kodowaniu ISO-8859-2, proszę więc zadbać o wysłanie odpowiedniego nagłówka ''Content-type''! - Napisz funkcję JS, która po kliknięciu przycisku wykona zapytanie AJAX do ww. skryptu, przyjmie dane i umieści je (jako ''innerHTML'') w odpowiednich elementach utworzonych w ramach zadania 1. ==== Ćwiczenie: walidacja XML ==== Pogodowe API jest funkcją nieoficjalną, dlatego też nie jest dla niego udostępniana specyfikacja formatu XML. Obserwując strukturę XML przykładowej odpowiedzi, stwórz plik DTD pozwalający na weryfikację poprawności (i np. wychwycenie ew. zmian formatu wprowadzonych przez dostawcę). Zwróć uwagę, że: * element ''current_conditions'' jest obowiązkowy i może wystąpić tylko raz, * elementy ''forecast_conditions'' występują zawsze po ''current_conditions'', są opcjonalne i mogą pojawić się 0 lub więcej razy. Następnie proszę zwalidować poniższe pliki i sprawdzić, czy zostanią w nich wychwycone błędy np. za pomocą parsera ''xmlstarlet'' (uwaga: na wstępie proszę sprawdzić, czy jest odpowiednio zdefiniowane kodowanie znaków diakrytycznych): xmlstarlet val -e -d weather.dtd krakow-bad-iso.xml Pliki: {{:pl:tiim:krakow_bad_iso.xml}} {{:pl:tiim:krakow_bad_iso1.xml}} {{:pl:tiim:krakow_bad_iso2.xml}} {{:pl:tiim:krakow_bad_iso3.xml}} ==== Ćwiczenie: JSON ==== Celem tego ćwiczenia jest porównanie implementacji mechanizmów AJAX wykorzystujących XML oraz JSON. JSON ([[http://en.wikipedia.org/wiki/JSON|JavaScript Object Notation]]) jest formatem serializacji obiektów w języku JavaScript. Dlatego też "odserializowanie" JSONa jest możliwe przy pomocy funkcji funkcji [[http://www.w3schools.com/jsref/jsref_eval.asp|eval]]; bezpieczniej jest jednak użyć zewnętrzengo parsera ([[http://www.json.org/js.html|więcej informacji]]). Pełny opis składni dostępny jest na [[http://www.json.org/json-pl.html|tej stronie]], [[http://json.org/example.html|tu]] jest kilka przykładów. W ramach ćwiczenia proszę przerobić skrypt (//backend//) PHP oraz JavaScript przygotowany w ramach ćwiczenia [[#cwiczeniexml_i_js|"XML i JS"]] tak, aby wykorzystywany był format JSON. W szczególności: - Skrypt PHP powinien parsować XML z pogodą (np. poprzez stworzenie elementu [[http://php.net/manual/pl/book.simplexml.php|SimpleXMLIterator]]) i generować z tych danych JSON (najłatwiej [[http://php.net/manual/pl/function.json-encode.php|tak]]). - JavaScript należy uprościć tak, aby wykorzystywał //responseText// zamiast //responseXML// i iterował po nim po zdeserializowaniu (zob. uwagi powyżej). ==== Ćwiczenie: XSLT ==== XSLT umożlwia definiowanie transformacji dokumentów XML do innych postaci. {{ :pl:tiim:xml-xslt.png }} 1. Niniejszy {{:pl:tiim:weather-txt.xsl|przykład}} obrazuje prostą transformację XSLT pliku XML do formatu tekstowego (proszę zwrócić uwagę na element ''xsl:output''). Przetestuj działanie tej transformacji korzystając z jednego z dostępnych na borgu parserów XML (zakładając, że dane o pogodzie w formacie XML, znajdują się w pliku ''weather.xml''): xmlstarlet tr weather-txt.xsl weather.xml xsltproc weather-txt.xsl weather.xml sabcmd weather-txt.xsl weather.xml 2. Przeglądarka WWW jest również wyposażona w parser XML, dodając odpowiednie dyrektywy do dokumentu xml (np. ''%%%%'') można poprosić parser o jego przetworzenie. Zobacz jak wyglada w przeglądarce dokument {{:pl:tiim:weather-xslt.xml}} (uwaga: w tym samym katalogu co ''weather-xslt.xml'' musi być dostępny dokument opisujący transformację ''weather-txt.xsl''). 3. Zmodyfikuj ''weather-txt.xsl'' tak aby generował kod XHTML a nie czysty tekst. Możesz zacząć od uzupełnienia prostego przykładu: {{:pl:tiim:weather-html.xsl|}} Postaraj się wykorzystać adresy ikon reprezentujących stan pogody (adresy są bezwzględne, trzeba je odpowiednio uzupełnić). Przetestuj działanie transformacji za pomocą wybranego parsera, oraz przeglądarki WWW (dodając odpowiedni element ''''). 4. Do konwersji XML->JSON można również wykorzystać XSLT. Na dokumencie zawierającym informacje o pogodzie przetestuj transformację {{:pl:tiim:xml2json.xsl}} pochodzącą z: http://xml2json.duttke.de/