Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Rozdział 12. WML, ASP, JSP, serwlety i Perl W tym rozdziale zajmiemy się kilkoma różnymi tematami, między innymi Bezprzewodowym językiem znaczników (WML, Wireless Markup Language), czyli popularną aplikacją XML przeznaczoną do użycia w telefonach komórkowych, PDA i innych prostych urządzeniach elektronicznych obsługujących protokół WAP (Wireless Application Protocol). WML jest językiem prostym, obecnie można się na niego już w wielu miejscach natknąć, a nowe serwery WAP pojawiają się jak grzyby po deszczu. W tym rozdziale dużo uwagi poświęcimy tworzeniu dokumentów WML i oglądaniu ich w przeglądarkach WML (często nazywanych mikroprzeglądarkami). W tym rozdziale zajmiemy się także użyciem XML w połączeniu z istniejącymi technologiami działającymi po stronie serwera, takimi jak Active Server Pages (ASP), Java Server Pages (JSP), serwlety Javy i Perl. Wiele firm usiłuje teraz zaistnieć na rynku XML/Internet, wobec czego pojawia się mnóstwo oprogramowania zajrzyj na stronę Microsoftu pod adres http://msdn.microsoft.com/xml/demos/default.asp, gdzie znajdziesz zestawienie. Jedną z popularnych technologii działających po stronie serwera jest Prosty protokół dostępu do obiektów (SOAP, Simple Object Access Protocol). Jest to faktycznie prosty protokół, który umożliwia wymianę komunikatów w środowisku rozproszonym, przy czym komunikaty zapisane są w XML. SOAP często jest używany do wysyłania poleceń w nagłówkach HTTP, gdyż protokoły zdalnego wywołania metod, takie jak DCOM Microsoftu, nie są ani dość proste, ani dość elastyczne, aby można je było zastosować w Internecie. Trzeba zresztą powiedzieć, że Microsoft jest jednym z głównych promotorów SOAP, co może kazać się zastanowić nad przyszłością DCOM. Nad SOAP także intensywnie pracują IBM i Lotus. Więcej o SOAP Trudno jest w Internecie znalezć informacje o SOAP, gdyż w języku angielskim słowo to oznacza po prostu mydło i wśród odpowiedzi większość dotyczyła będzie czystości i telewizyjnych tasiemców ( opery mydlane ). Na początek możesz zatem poszukiwania zacząć od następujących adresów: " http://msdn.microsoft.com/xml/general/soapspec.asp D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 1 2 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) " www.oasis-open.org/cover/soap.html " www.develop.com/soap " www.develop.com/soap/soapfaq.xml Tutaj koniec ramki Wyróżnienie W tym rozdziale przyjrzymy się też tworzeniu dokumentów XML po stronie serwera. W tym celu będziemy pobierać dane z pliku bazy danych db.mdb w zwykłym formacie Microsoft Access. Następnie dane będziemy formatować w XML i przesyłać wynikowe dokumenty do komputerów klienckich. Baza danych jest bardzo prosta, zawiera jedynie imiona ośmiorga studentów wraz z ich oceną wyrażoną literą tabela 12.1. Tabela 12.1. Studenci z pliku db.mdb Student Ocena Ann C Mark B Ed A Frank A Ted A Mabel B Ralph B Tom B Zaczniemy od zastosowania Obiektów danych ActiveX (ADO, ActiveX Data Objects) zainstalowanych na serwerze przeszukujących bazę danych i tworzących dokument XML wyświetlany za pomocą Active Server Pages. Programowanie po stronie serwera W pierwszej części tego rozdziału, kiedy opisywać będziemy programowanie od strony serwera, wiele technologii omówionych zostanie bardzo pobieżnie. Niestety nie sposób omówić tutaj wszystkiego, co potrzebne do programowania Active Server Pages, Java Server Pages, serwletów Javy czy Perla. Jeśli potrzebne będą Ci dodatkowe informacje, musisz poszukać ich gdzie indziej. Kiedy w drugiej części tego rozdziału omawiać będziemy WML, tego rodzaju ograniczeń już nie będzie zaczniemy omawianie wszystkiego od samego początku. XML i Active Server Pages Active Server Pages (ASP) to technologia internetowa działająca po stronie serwera zaproponowana przez Microsoft, która umożliwia tworzenie dokumentów w locie. Dokumenty tworzone są na serwerach takich, jak Microsoft Internet Information Server (IIS); w naszym 2 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) wypadku wyszukamy imiona w bazie db.mdb i zwrócimy je w postaci następującego dokumentu XML:
Ann
Mark
Ed
Frank
Ted
Mabel
Ralph
Tom
Najważniejsze w przypadku ASP to upewnić się, że kod wygeneruje dokument XML, gdyż domyślnym typem dokumentu jest HTML. Jeśli opis typu zawartości w nagłówku HTTP nie zawiera informacji, że mamy do czynienia z dokumentem XML, przeglądarka dokumentu tego nie potraktuje jako XML (i zapewne potraktuje go jako HTML). Typ zawartości określa się za pomocą instrukcji <% Response.ContentType %> podając typ application/xml: <% Response.ContentType = "application/xml" %> . . . Następnie dodajemy deklarację XML oraz element główny, document: <% Response.ContentType = "application/xml" %>
. . . Teraz potrzebne nam są imiona studentów z bazy db.mdb. Użyjemy do tego protokołu ADO Microsoftu, gdyż ASP przeznaczony jest do pracy na platformach Windows, takich jak IIS. Utworzymy połączenie ADO oraz użyjemy instrukcji SQL pobierającej zestaw wszystkich rekordów: <% Response.ContentType = "application/xml" %>
<% D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 3 4 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) DIM adoConnect DIM adoRecordset Set adoConnect = Server.CreateObject("ADODB.Connection") adoConnect.open "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=C:\xml\db.mdb" Set adoRecordset = adoConnect.Execute("SELECT * FROM Students") . . . Teraz pozostało nam już tylko zorganizować pętlę po wszystkich rekordach i utworzyć w każdym przejściu element XML student: <% Response.ContentType = "application/xml" %>
<% DIM adoConnect DIM adoRecordset Set adoConnect = Server.CreateObject("ADODB.Connection") adoConnect.open "Provider=Microsoft.Jet.OLEDB.4.0;" _ & "Data Source=C:\xml\db.mdb" Set adoRecordset = adoConnect.Execute("SELECT * FROM Students") Do While Not adoRecordset.EOF Response.Write "" + adoRecordset("Name") + "" adoRecordset.MoveNext Loop adoRecordset.Close set adoRecordset = Nothing %>
W ten sposób utworzony zostanie potrzebny nam dokument XML, co pokazano na rysunku 12.1. Nie mogę wykonać rysunku, gdyż wymaga IIS. Rysunek można Rysunek 12.1. zeskanować z książki (dlatego właśnie nie zmieniłem Tworzenie znaczników document na dokument ani nie zmieniałem dokumentu XML imion na polskie odpowiedniki. za pomocą ASP Rysunek powinien być taki jak poniżej, ale inny powinien być pasek tytułu (jak w książce); to samo dotyczy rysunków 12.2 i 12.3. 4 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Zwróć uwagę na to, że następne rysunki będą bardzo podobne do powyższego; aby zauważyć różnice między nimi, dokładnie przyglądaj się paskom tytułu przeglądarki. XML i serwlety Javy Serwlety Javy mają być dla serwerów sieciowych tym, czym są aplety Javy dla komputerów klienckich. Serwletów można użyć do tworzenia dokumentów sieciowych na różnych serwerach. Aby tworzyć serwlety, możesz załadować Java Servlet Development Kit (JSDK) ze strony java.sun.com (w chwili pisania strona główna poświęcona serwletom to http://java.sun.com/products/servlet/index.html) i tworzyć serwlety za pomocą klas z archiwów servlet.jar i server.jar. Aby odczytać z bazy danych db.mdb imiona studentów, użyjemy pakietu JDBC (Java Database Connectivity) łącząc się z db.mdb po zarejestrowaniu bazy danych jako zródła danych ODBC. Kiedy wyszukamy już imiona studentów, umieścimy je w dokumencie XML i dokument ten odeślemy do klienta. Znów najważniejsze jest stworzenie dokumentu XML, a nie domyślnego HTML. W przypadku serwletów dokument XML tworzy się za pomocą metody setContentType klasy ServletResponse podając jako typ zawartości application/xml: import java.net.*; import java.sql.*; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.servlet.*; public class xml extends GenericServlet { public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { response.setContentType("application/xml"); . . . Następnie zwracamy klientowi deklarację XML i element główny: import java.net.*; import java.sql.*; import java.awt.*; import java.awt.event.*; import java.io.*; D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 5 6 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) import javax.servlet.*; public class xml extends GenericServlet { public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { response.setContentType("application/xml"); PrintWriter printwriter = response.getWriter(); printwriter.println("2\"?>"); printwriter.println(""); . . . Teraz możemy użyć JDBC do utworzenia zbioru wyników zawierającego wszystkie rekordy z bazy db.mdb: import java.net.*; import java.sql.*; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.servlet.*; public class xml extends GenericServlet { public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { response.setContentType("application/xml"); PrintWriter printwriter = response.getWriter(); printwriter.println("2\"?>"); printwriter.println(""); try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); connection = DriverManager.getConnection( "jdbc:odbc:students", "Steve", "password"); statment = connection.createStatement(); String SQL = "SELECT Name FROM Students"; ResultSet resultset = statement.executeQuery(SQL); . . . Teraz już tylko musimy utworzyć pętlę po zbiorze wyników, w której pobierzemy imiona studentów i odeślemy je do klienta zamknięte elementami student: import java.net.*; import java.sql.*; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.servlet.*; 6 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) public class xml extends GenericServlet { public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException { response.setContentType("application/xml"); PrintWriter printwriter = response.getWriter(); printwriter.println("2\"?>"); printwriter.println(""); try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); connection = DriverManager.getConnection( "jdbc:odbc:students", "Steve", "password"); statment = connection.createStatement(); String SQL = "SELECT Name FROM Students"; ResultSet resultset = statement.executeQuery(SQL); while (resultset.next()) { printwriter.println(" + resultset.getString(1) + ""); } } catch(Exception e) {} printwriter.println(""); printwriter.close(); } } I to już wszystko. Wynik działania serwleta pokazano na rysunku 12.2, gdzie do klienta zwrócony został ten sam dokument, co w przypadku omawianego poprzednio ASP. Nie mogę wykonać rysunku, gdyż wymaga serwera Rysunek 12.2. HTTP/WWW. Rysunek można zeskanować z książki (dlatego Tworzenie właśnie nie zmieniłem znaczników document na dokument dokumentów ani nie zmieniałem imion na polskie odpowiedniki. za pomocą serwletów Javy Kolejną zdobywającą popularność technologią z wykorzystaniem Javy jest użycie Java Server Pages, co omówiono w następnym podrozdziale. Java Server Pages Java Server Pages (JSP) to reakcja środowiska Javy na Active Server Pages Microsoftu. JSP umożliwia tworzenie dynamicznych stron sieciowych przez uruchamianie skryptów na serwerze. Dokładny opis JSP znajdziesz na stronie http://java.sun.com/products/jsp/index.html. JSP używa się podobnie jak ASP. D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 7 8 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) W tym przykładzie użyjemy serwera Apache Tomcat będącego oficjalnie wzorcową implementacją JSP (a także serwletów Javy). Serwer ten możesz ściągnąć ze strony http://jakarta.apache.org/tomcat/. Utworzymy taki sam dokument XML jak w dwóch poprzednich przykładach na podstawie danych z bazy db.mbd. Jako że powtórnie korzystamy z Javy, znów użyjemy do sięgania do bazy danych JDBC. Znów na początek musimy zapewnić prawidłową interpretację typu dokumentu, aby użyty został typ application/xml, a nie domyślny HTML. W JSP korzysta się z atrybutu contentType: <%@ page language="java" contentType="application/xml" import="java.sql.*" %> . . . Znów inicjalizujemy sterownik JDBC: <%@ page language="java" contentType="application/xml" import="java.sql.*" %> <% Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); %> . . . Następnie wstawiamy deklarację XML oraz element główny: <%@ page language="java" contentType="application/xml" import="java.sql.*" %> <% Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); %>
. . . Teraz pobieramy zbiór wyników z JDBC rekordy wszystkich studentów zwrócone przez zapytanie SQL: <%@ page language="java" contentType="application/xml" import="java.sql.*" %> <% Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); %>
<% Connection connection = DriverManager.getConnection( "jdbc:odbc:students", "Steve", "password"); Statement statement = connection.createStatement(); ResultSet resultset = statement.executeQuery("select * from Students"); %> . . . 8 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Teraz już pozostało tylko utworzenie pętli po studentach i wygenerowanie elementów student: <%@ page language="java" contentType="application/xml" import="java.sql.*" %> <% Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); %>
<% Connection connection = DriverManager.getConnection( "jdbc:odbc:students", "Steve", "password"); Statement statement = connection.createStatement(); ResultSet resultset = statement.executeQuery("select * from Students"); %> <% while(resultset.next()){ %> <%= resultset.getString() %> <% } %> Na rysunku 12.3 pokazano wyniki działania skryptu JSP. Jak widać, wyniki wcale nie są gorsze niż w przypadku zastosowania ASP, zresztą znam bardzo wielu programistów XML, którzy do udostępniania dokumentów XML wolą właśnie JSP zamiast ASP, gdyż praca z XML w Javie jest niejako naturalna, o czym można było się przekonać w rozdziałach 8 i 9 niniejszej książki. Rysunek wymaga serwera Tomcat, który w mojej konfiguracji Rysunek 12.3. nie działa. Rysunek można zeskanować z książki (dlatego Tworzenie właśnie nie zmieniłem znaczników document na dokument dokumentów XML ani nie zmieniałem imion na polskie odpowiedniki. za pomocą Java Server Pages XML i Perl Praktyczny język pobierania danych i raportowania (PERL, Practical Extraction and Reporting Language) przez długi czas był podstawowym narzędziem do programowania serwerów i podstawą CGI. Język ten też szybko znalazł zastosowanie do obsługi XML, nietrudno byłoby na ten temat napisać osobną książkę. Moduły Perla rozproszone są po sieciowym archiwum Perla (CPAN, Comprehensive Perl Archive Network) dostępnym pod adresem www.cpan.org, wiele z tych modułów służy do obsługi XML (autor doliczył się 156 takich modułów). W tabeli 12.2 zestawiono wybrane moduły wraz z ich opisem podawanym w witrynie CPAN. Tabela 12.2. Moduły Perla do obsługi XML wraz z opisem z CPAN Moduł Opis Apache::AxKit::XMLFi Wykrywa pliki XML nder D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 9 10 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Apache::MimeXML Nasłuchiwacz typów kodowania mime mod_perl wyszukujący pliki XML. Boulder::XML Procedury formatowania XML strumieni wejściowo wyjściowych Boulder. Bundle::XML Pakiet instalujący wszystkie moduły powiązane z XML. CGI::XMLForm Rozszerzenie CGI.pm odczytujące/generujące sformatowany XML. Data::DumpXML Zapisuje dowolne struktury danych jako XML. DBIx::XML_RDB Rozszerzenie Perla służące do generacji XML na podstawie istniejących zródeł danych DBI. GoXML::XQI Rozszerzenie Perla służące do obsługi interfejsu XML Query w xqi.goxml.com. Mail::XML Dodaje do Mail::Internet metodę toXML(). MARC::XML Podklasa MARC.pm zapewniająca obsługę XML. PApp::XML Sekcje pxml i inne. XML::Catalog Rozwija identyfikatory publiczne i przekształca identyfikatory systemowe. XML::CGI Rozszerzenie Perla służące do konwersji zmiennych CGI.pm z/na XML. XML::Checker Moduł Perla służący do walidacji XML. XML::Checker::Parser XML::Parser walidujący podczas parsowania dokumentów. XML::DOM Moduł Perla służący do tworzenia struktur dokumentów zgodnych z DOM Level 1. XML::DOM::NamedNodeM Interfejs tablic haszujących dla XML::DOM. ap XML::DOM::NodeList Listy węzłów używane przez XML::DOM. XML::DOM::PerlSAX Stara nazwa XML::Handler::BuildDOM. XML::DOM::ValParser XML::DOM::Parser walidujący w czasie parsowania. XML::Driver::HTML Sterownik SAX przeznaczony dla HTML nie sformułowanego poprawnie w rozumieniu XML. XML::DT Pakiet przekształcania XML na napisy. XML::Edifact Moduł Perla obsługujący komunikaty XML::Edifact. XML::Encoding Moduł Perla do parsowania map kodowania XML. XML::ESISParser Parser PerlSAX używający nsgmls. 10 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) XML::Filter::DetectW Filtr PerlSAX wykrywający białe znaki, które mogą zostać S pominięte. XML::Filter::Hekeln Edytor strumieniowy SAX. XML::Filter::Reinden Uzupełnia białe znaki, aby uzyskać dokument XML w ładnej t graficznie postaci. XML::Filter::SAXT Replikuje zdarzenia SAX kilku procedurom obsługi zdarzeń SAX. XML::Generator Rozszerzenie Perla do generacji XML. XML::Grove Perlopodobne obiekty XML. XML::Grove::AsCanonX Wyprowadza obiekty XML w postaci kanonicznego XML. ML XML::Grove::AsString Wyprowadza treść obiektów XML jako napisy. XML::Grove::Builder Procedura obsługi PerlSAX do tworzenia XML::Grove. XML::Grove::Factory Upraszcza tworzenie obiektów XML::Grove. XML::Grove::Path Zwraca obiekt z podanej ścieżki. XML::Grove::PerlSAX Interfejs zdarzeń PerlSAX dla obiektów XML. XML::Grove::Sub Uruchamia procedurę filtrującą na dokumencie. XML::Grove::Subst Podstawia wartości do szablonu. XML::Handler::BuildD Procedura obsługi PerlSAX tworząca struktury dokumentu OM XML::DOM. XML::Handler::CanonX Wyprowadza dane w postaci kanonicznego XML. MLWriter XML::Handler::Compos Generuje, drukuje i zapisuje XML. er XML::Handler::PrintE Drukuje zdarzenia PerlSAX (przydatne przy usuwaniu błędów vents w programach). XML::Handler::PyxWri Przekształca zdarzenia PerlSAX na ESIS nsgmls. ter XML::Handler::Sample Elementarna procedura obsług zdarzeń PerlSAX. XML::Handler::Subs Klasa bazowa procedury obsługi zdarzeń PerlSAX przeznaczona do wywoływania procedur zdefiniowanych przez użytkownika. XML::Handler::XMLWri Procedura obsługi zdarzeń PerlSAX przeznaczona do wypisania ter czytelnego dla człowieka XML. XML::Handler::YAWrit Kolejny PerlSAX XML Writer 0.15. er D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 11 12 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) XML::Node Oparte na obsłudze węzłów parsowanie XML; uproszczony interfejs do XML. XML::Parser Moduł Perla do parsowania dokumentów XML. XML::Parser::Expat Parser expat Jamesa Clarka umożliwiający dostęp niskiego poziomu. XML::Parser::PerlSAX Parser PerlSAX używający XML::Parser. XML::Parser::PyxPars Konwertuje ESIS nsgmls lub Pyxie na PerlSAX. er XML::PatAct::Amsterd Moduł procedur do uproszczonych arkuszy stylów. am XML::PatAct::MatchNa Moduł wzorców do dobierania nazw elementów. me XML::PatAct::ToObjec Moduł procedur do tworzenia obiektów Perla. ts XML::PYX Generator XML na PYX. XML::QL Język zapytań XML. XML::RegExp Wyrażenia regularne dla nazw XML. XML::Registry Moduł Perla ładujący i zapisujący rejestry XML. XML::RSS Tworzy i aktualizuje pliki RSS. XML::SAX2Perl Przekształca metody PerlSAX na metody w stylu Java/CORBA. XML::Simple Elementarny interfejs API do czytania i zapisywania XML (szczególnie plików konfiguracyjnych). XML::Stream Tworzy połączenie XML i parsuje dane zwrotne. XML::Stream::Namespa Obiekt ułatwiający definiowanie przestrzeni nazw. ce XML::Template Instancja szablonu Perl XML. XML::Twig Moduł Perla przeznaczony do przetwarzania bardzo dużych dokumentów XML jako drzewek. XML::UM Przekształca napisy UTF-8 na dowolne kodowanie obsługiwane przez XML::Encoding. XML::Writer Rozszerzenie Perla przeznaczone do zapisywania dokumentów XML. XML::XPath Zestaw modułów do parsowania i interpretacji XPath. XML::XPath::Boolean Logiczne wartości prawdy i fałszu. XML::XPath::Builder Procedura obsługi zdarzeń SAX do tworzenia drzewka XPath. 12 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) XML::XPath::Literal Proste wartości tekstowe. XML::XPathNode Wewnętrzna reprezentacja węzła. XML::XPath::NodeSet Lista węzłów dokumentu XML. XML::XPath::Number Proste wartości numeryczne. XML::XPath::PerlSAX Generator zdarzeń PerlSAX. XML::XPath::XMLParse Domyślna klasa parsowania XML dająca drzewo węzłów. r XML::XQL Moduł Perla do zadawania zapytań dotyczących drzewiastych struktur XML za pomocą XQL. XML::XQL::Date Dodaje typ XQL::Node służący do reprezentacji i porównywania wartości daty i czasu. XML::XQL::DOM Dodaje do węzłów XML::DOM obsługę XQL. XML::XSLT Moduł Perla do przetwarzania XSLT. XMLNews::HTMLTemplat Moduł do konwersji NITF na HTML. e XMLNews::Meta Moduł do odczytu i zapisu plików metadanych XMLNews. Większość modułów Perl z tabeli 12.2 trzeba przed użyciem ściągnąć i zainstalować (proces ten jest żmudny, choć prosty; zarówno w Windows, jak i w UNIXie istnieją narzędzia zarządzające ładowaniem i instalacją). Standardowa dystrybucja Perla zawiera wbudowaną częściową obsługę XML, na przykład moduł XML::Parser. Oto przykład użycia modułu XML::Parser. W tym wypadku parsować będziemy dokument XML i za pomocą Perla go wydrukujemy. Moduł XML::Parser może obsłużyć wywołania zwrotne, czyli wywoływać podprocedury na początku elementu, przy treści i przy końcu elementu. Oto jak przygotowujemy takie wywołania wiążąc je z procedurami obsługi zdarzeń start_handler, char_handler oraz end_handler tworząc nowy obiekt parsera $parser: use XML::Parser; $parser = new XML::Parser(Handlers => {Start => \&start_handler, End => \&end_handler, Char => \&char_handler}); . . . Teraz potrzebny jest nam dokument XML, który będziemy parsować. Użyjemy dokumentu spotkania.xml z rozdziału 5:
Ted Bond XML w praktycznych zastosowaniach 2079 XML D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 13 14 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) 6/1/2002 Edward Samson
Ernestyna Johnson
Betty Richardson
Metoda parsefile obiektu $parser umożliwia nam parsowanie tego dokumentu: use XML::Parser; $parser = new XML::Parser(Handlers => {Start => \&start_handler, End => \&end_handler, Char => \&char_handler}); $parser->parsefile('spotkania.xml'); . . . Teraz wystarczy już tylko utworzyć podprocedury start_handler, char_handler i end_handler. Zaczniemy od pierwszej z nich, która wywoływana jest przy napotkaniu początku elementu XML. Nazwa elementu zapisywana jest w pierwszej komórce standardowej tablicy Perla $_ zawierającej argumenty podprocedur. Element ten wraz ze znacznikiem początkowym możemy wyświetlić następująco: use XML::Parser; $parser = new XML::Parser(Handlers => {Start => \&start_handler, End => \&end_handler, Char => \&char_handler}); $parser->parsefile('spotkania.xml'); sub start_handler { print "<$_[[1]>\n"; } . . . Podobnie drukujemy znacznik końcowy w podprocedurze end_handler: use XML::Parser; $parser = new XML::Parser(Handlers => {Start => \&start_handler, End => \&end_handler, Char => \&char_handler}); $parser->parsefile('spotkania.xml'); 14 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) sub start_handler { print "<$_[[1]>\n"; } sub end_handler { print "$_[1]>\n"; } . . . Z kolei dane elementu możemy wydrukować w podprocedurze char_handler, pominiemy tylko zbędne spacje: use XML::Parser; $parser = new XML::Parser(Handlers => {Start => \&start_handler, End => \&end_handler, Char => \&char_handler}); $parser->parsefile('spotkania.xml'); sub start_handler { print "<$_[[1]>\n"; } sub end_handler { print "$_[1]>\n"; } sub char_handler { if(index($_[1], " ") < 0 && index($_[1], "\n") < 0){ print "$_[1]\n"; } } Program jest już gotowy, uruchomienie takiego skryptu Perla da wynik taki, jak pokazano poniżej: Ted Bond
XML w praktycznych zastosowaniach
2079
XML
6/1/2002
D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 15 16 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Edward
Samson
Ernestyna
Johnson
Betty
Richardson
Jak zapewne zauważyłeś, parsowanie dokumentu i definiowanie funkcji zwrotnych w Perlu bardzo przypomina to, co robiliśmy w rozdziale 9, kiedy omawialiśmy interfejs SAX. Teraz przyjrzymy się udostępnianiu dokumentów XML przez skrypty Perla. Niestety, Perl nie zawiera tak rozbudowanego protokołu komunikacji z bazą danych jak JDBC wraz z odpowiednim ODBC lub ASP z ADO. Obsługa baz danych wbudowana w Perl oparta jest na plikach DBM, które mają strukturę haszowanych baz danych. Możesz też oczywiście zainstalować moduły Perla, które pozwalają obsługiwać wszelakie bazy danych, od ODBC po Oracle. W naszym przypadku użyjemy skryptu Perla, który umożliwi podanie klucza (na przykład warzywo) wraz z wartością (na przykład brokuły), taka para będzie przechowywana w bazie danych w formacie NDBM domyślnie obsługiwanym przez Perla. Baza danych znajdować się będzie na serwerze. Kiedy użytkownik poda klucz na stronie, nasz program wyszuka w bazie danych odpowiednie rekordy i jeśli jakieś znajdzie, zwróci klucze wraz z ich wartościami. Jeśli na przykład wpiszesz jako klucz warzywo, jako wartość brokuły, taka para zostanie dopisana do bazy danych. Kiedy następnie wyszukiwać będziesz klucza warzywo, skrypt zwróci klucz wraz z odpowiadającą mu wartością w postaci dokumentu XML:
warzywo brokuły
Na rysunku 12.4 pokazano wyniki działania skryptu CGI. Aby dodać do bazy nowy rekord, wpisuje się klucz i odpowiadającą mu wartość, następnie klika przycisk Dodaj. Na rysunku 12.4 właśnie dodawana jest wartość brokuły z kluczem warzywo. 16 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Rysunek 12.4. Perlowy skrypt CGI jako program obsługi bazy danych Aby pobrać z bazy danych wartość, wpisuje się w pole szukany klucz i klika przycisk Szukaj. Baza danych jest przeszukiwana, a wyniki w postaci dokumentu XML są odsyłane do klienta, co pokazano na rysunku 12.5. W tym wypadku wyszukiwany był klucz warzywo. Wprawdzie uzyskany dokument XML wyświetlany jest w przeglądarce, ale dość prosto jest za pomocą wtyczek internetowych (Internet sockets) Perla taki dokument obsłużyć także bez przeglądarki. Rysunek został wykonany inną metodą, bezwzględnie Rysunek 12.5. konieczne jest usunięcie przez grafika z paska tytułu nazwy Dokument XML pliku i pozostawienie tam tylko po lewo napisu Microsoft generowany Internet Explorer ! przez skrypt Perl W tym skrypcie użyjemy standardowo do Perla dołączanego modułu CGI.pm. Zaczniemy od utworzenia strony sieciowej z rysunku 12.4 zawierającej między innymi potrzebne kontrolki HTML: #!/usr/local/bin/perl use Fcntl; use NDBM_File; use CGI; $co = new CGI; if(!$co->param()) { print $co->header, $co->start_html('Przykład funkcji CGI'), $co->center($co->h1('Przykład bazy danych CGI')), $co->hr, $co->b("Dodanie pary klucz/wartość do bazy danych..."), $co->start_form, "Klucz dodawany do bazy: ", $co->textfield(-name=>'key', -default=>'', -override=>1), $co->br, "Wartość dodawana do bazy danych: ", $co->textfield(-name->'value', -default=>'', -override=>1), $co-br, $co->hidden(-name=>'type', -value=>'write', -override=>1), $co->br, $co->center( $co->submit('Dodaj'), $co>reset ), $co->end_form, D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 17 18 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) $co-hr, $co->b("Wyszukiwanie wartości w bazie danych..."), $co->start_form, "Szukany klucz: ", $co->textfield(-name=>'key', -default=>'', - override=>1), $co->br, $co->hidden(-name=>'type',-value=>'read', -override=>1), $co->br, $co->center( $co->submit('Wyszukanie wartości'), $co->reset ), $co->end_form, $co->hr; print$co->end_html; } . . . Ten skrypt CGI utworzy dwa formularze HTML: jeden do zapisywania par klucz/wartość do bazy, drugi do wyszukiwania wartości odpowiadającej kluczowi. Nie wskazaliśmy, gdzie dane z formularzy mają być przesyłane, wobec czego zostaną odesłane do tego samego skryptu. To, czy skrypt otrzymał przy wywołaniu jakieś dane do przetwarzania, możemy sprawdzić sprawdzając wartość zwróconą przez metodę CGI.pm param. Jeśli otrzymamy wartość true, jakieś dane już czekają na przetwarzanie. Zwracany przez ten skrypt dokument jest dokumentem XML, a nie domyślnym HTML, zatem konieczne jest wskazanie tego w nagłówku HTTP, w opisie typu zawartości. Używamy metody header, jej parametrowi type przypisujemy wartość application/xml. Oto fragment kodu skryptu znajdujący się bezpośrednio za kodem dotąd napisanym: if($co->param()) { print $co->header(-type=>"application/xml"); print ""; print ""; . . . Rozdzieliliśmy dwa formularze HTML dodając dla rozróżnienia zmienną1 type. Jeśli zmienna ta ma wartość write, podane przez użytkownika dane mają być dopisane do bazy danych: if($co->param()) { print $co->header(-type=>"application/xml"); print ""; print ""; if($co->param('type') eq 'write') { tie %dbhash, "NDBM_File", "dbdata", O_RDWR|O_CREATE, 0644; $key = $co->param('key'); $value = $co->param('value'); $dbhash{$key} = $value; untie %dbhash; if ($!) { print "Wystąpil błąd: $!"; } else { print "$key=>$value zostały zapisane w bazie danych"; 1 Właściwie pole ukryte formularza. (przyp. tłum.) 18 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) } } . . . } W przeciwnym wypadku szukamy w bazie danych podanego klucza i zwracamy klucz wraz z wartością w postaci dokumentu XML: if($co->param()) { print $co->header(-type=>"application/xml"); print ""; print ""; if($co->param('type') eq 'write') { tie %dbhash, "NDBM_File", "dbdata", O_RDWR|O_CREATE, 0644; $key = $co->param('key'); $value = $co->param('value'); $dbhash{$key} = $value; untie %dbhash; if ($!) { print "Wystąpil błąd: $!"; } else { print "$key=>$value zostały zapisane w bazie danych"; } } else { tie %dbhash, "NDBM_File", "dbdata", O_RDWR|O_CREAT, 0644; $key = $co->param('key'); $value = $dbhash{$key}; $value = $dbhash{$key}; print ""; print $key; print ""; print "; print $value; print "; if ($value) { if ($!) { print "Wystąpił błąd: $!"; } } else { print "Brak wartości dla podanego klucza"; } untie %dbhash } print ""; } W ten sposób utworzyliśmy skrypt Perl, który umożliwia zapisywanie danych w bazie i odczytywanie ich w postaci XML. Na wydruku 12.1 pokazano pełny kod programu, dbxml.cgi. Oczywiście samodzielne robienie wszystkiego jest trudnym zadaniem jeśli zamierzasz zająć się obsługą XML w Perlu, powinieneś przyjrzeć się dokładniej licznym modułom Perla do obsługi XML udostępnionym w CPAN. Wydruk 12.1. dbxml.cgi #!/usr/local/bin/perl use Fcntl; use NDBM_File; use CGI; $co = new CGI; D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 19 20 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) if(!$co->param()) { print $co->header, $co->start_html('Przykład funkcji CGI'), $co->center($co->h1('Przykład bazy danych CGI')), $co->hr, $co->b("Dodanie pary klucz/wartość do bazy danych..."), $co->start_form, "Klucz dodawany do bazy: ", $co->textfield(-name=>'key', -default=>'', -override=>1), $co->br, "Wartość dodawana do bazy danych: ", $co->textfield(-name->'value', -default=>'', -override=>1), $co-br, $co->hiddent(-name=>'type', -value=>'write', -override=>1), $co->br, $co->center( $co->submit('Dodaj'), $co>reset ), $co->end_form, $co-hr, $co->b("Wyszukiwanie wartości w bazie danych..."), $co->start_form, "Szukany klucz: ", $co->textfield(-name=>'key', -default=>'', - override=>1), $co->br, $co->hidden(-name=>'type',-value=>'read', -override=>1), $co->br, $co->center( $co->submit('Wyszukanie wartości'), $co->reset ), $co->end_form, $co->hr; print$co->end_html; } if($co->param()) { print $co->header(-type=>"application/xml"); print ""; print ""; if($co->param('type') eq 'write') { tie %dbhash, "NDBM_File", "dbdata", O_RDWR|O_CREATE, 0644; $key = $co->param('key'); $value = $co->param('value'); $dbhash{$key} = $value; untie %dbhash; if ($!) { print "Wystąpil błąd: $!"; } else { print "$key=>$value zostały zapisane w bazie danych"; } } else { tie %dbhash, "NDBM_File", "dbdata", O_RDWR|O_CREAT, 0644; $key = $co->param('key'); $value = $dbhash{$key}; $value = $dbhash{$key}; print ""; print $key; print ""; 20 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) print "; print $value; print "; if ($value) { if ($!) { print "Wystąpił błąd: $!"; } } else { print "Brak wartości dla podanego klucza"; } untie %dbhash } print ""; } Bezprzewodowy język znaczników Jedną z aplikacji XML skupiających powszechną uwagę jest Bezprzewodowy język znaczników WML (Wireless Markup Language). WML i związany z nim protokół WAP przeznaczone są do obsługi przenośnych urządzeń takich jak telefony komórkowe, PDA i inne urządzenia o ograniczonych możliwościach technicznych. WML to język z mocno ograniczoną składnią, który łatwo jest w takich urządzeniach zastosować, programy ten język obsługujące w urządzeniach często nazywa się mikroprzeglądarkami. Oto lista wybranych zasobów na temat WML: " www.wapforum.org. Doskonały adres, pod którym znajdziesz mnóstwo o WML. Pełni rolę punktu zbiorczego. " http://wap.colorline.no/wap-faq/. Niezależne FAQ (często zadawane pytania) na temat WAP, zawierają mnóstwo informacji, między innymi listę firm oferujących usługi WAP. " www.apachesoftware.com. Wszystko o Klondike, popularnej przeglądarce WML. " hotfiles.zdnet.com/cgi-bin/texis/swlib/hotfiles/info.html?fcode=0018AV. Strona, z której można ściągnąć Klondike. " www.apachesoftware.com/wml/wmldemo.wml. Przykłady WML Klondike. " www.wap-uk.com/Developers/Tutorial.htm. Podręcznik WML. " www.wapdesign.org.uk/tutorial.html. Inny podręcznik WML. " www.wapdesign.org.uk/server.html. Podręcznik dla usługodawców WAP. " www.wapforum.org/DTD/wml_1.1.xml. DTD WML 1.1 (bieżącej wersji). Doskonałe miejsce, w którym można rozwiać wszelkie wątpliwości odnośnie składni. W tabeli 12.3 zestawiono elementy WML wraz z ich atrybutami. Tabela 12.3. Elementy WML Element Realizowana funkcja Atrybuty D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 21 22 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) a class href id title xml:lang hiperłącze access class domain id path element dostępu anchor class id title xml:lang pełni rolę zakładki b class id xml:lang pogrubienie big class id xml:lang powiększony tekst br class id xml:lang koniec wiersza card class do id label name tworzy kartę newcontext onenterbackward onenterforward ontimer optional ordered title type xml:lang em class id xml:lang akcentuje tekst fieldset class id title xml:lang zestaw pól go accept-charset class href id nawigacja method sendreferer head class id część nagłówkowa i class id xml:lang kursywa img align alt class height hspace obsługa obrazków id localsrc src vspace width xml:lang input class emptyok format id pole tekstowe maxlength name size tabindex title type value xml:lang meta class content forua http-equiv zawiera metadane id name scheme noop class id brak operacji (pomocniczy) onevent class id type obsługa zdarzenia optgroup class id title xml:lang tworzy grupę opcji option class id onpick title value opcja xml:lang p align mode xml:lang class id akapit postfield class id name value przesyła pole danych prev przejście do poprzedniej karty refresh class id obsługa odświeżania select class id iname ivalue multiple wybiera kontrolkę 22 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) name tabindex title value xml:lang setvar class id name value nadaje zmiennej wartość small class id xml:lang tekst pomniejszony strong class id xml:lang wyróżnienie tekstu table align class columns id title tworzy tabelę xml:lang td class id xml:lang komórka danych tabeli template class id onenterbackward szablon onenterforward ontimer timer class id name value tworzy zegar tr class id wiersz tabeli u class id xml:lang podkreślenie Oprócz tego WML obsługuje następujące encje znakowe: & symbol & ' apostrof (') > znak większości (>) < znak mniejszości (<)
spacja nierozdzielająca (' ') " cudzysłów (") łącznik opcjonalny ( ) W kolejnych punktach używać będziemy popularnej przeglądarki WML Apache Klondike, którą można pobrać z witryny www.apachesoftware.com. Przeglądarka ta jest dobrze opracowana i warto ją zainstalować. Zaczynamy poznawać WML Mikroprzeglądarki nie mają zbyt wielkich wyświetlaczy, wobec czego dokumenty WML dzieli się na karty, za każdym razem wyświetlana jest właśnie jedna taka karta. Dokument WML nazywany talią to zestaw takich kart. Talia ujęta jest w element wml, natomiast poszczególne karty w elementy card. Kiedy mikroprzeglądarka odczytuje dokument WML, od razu odczytuje całą talię mimo że na raz pokazywana jest pojedyncza karta. Dokument WML zaczyna się deklaracją XML:
. . . D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 23 24 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) W WML (podobnie jak w XHTML) używa się znacznika z formalnym identyfikatorem publicznym, tyle tylko, że ciałem standaryzacyjnym jest WAP Forum, a nie W3C:
"http://www.wapforum.org/DTD/wml_1.1.xml"> . . . Dokument czyli talia zaczyna się znacznikiem :
"http://www.wapforum.org/DTD/wml_1.1.xml"> . . .
Do tworzenia poszczególnych kart w talii używa się elementu card; naszej karcie nadamy identyfikator Card1 i tytuł Pierwszy przykład WML (tytuł pokazuje się w pasku tytułowym Klondike):
"http://www.wapforum.org/DTD/wml_1.1.xml"> . . .
W dokumentach WML komentarze wstawia się tak jak w zwykłym XML:
"http://www.wapforum.org/DTD/wml_1.1.xml">
. . .
Każda karta zawierać musi element p (czyli akapit), w naszym przykładzie w tym elemencie umieścimy krótkie pozdrowienie:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Pozdrowienia z WML.
24 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) I tak wygląda nasz pierwszy dokument. Na rysunku pokazano ten przykład w przeglądarce Klondike2. Rysunek 12.6. Pierwszy dokument WML Wyrównanie tekstu Element p ma atrybut align, który jest przydatny do określania sposobu wyrównania tekstu. Atrybutowi temu można przypisać jedną z wartości left, center lub right. Istnieje też atrybut mode, którego można użyć, czy tekst ma być zawijany, czy też nie odpowiednio wartości wrap lub nowrap. W poniższym przykładzie pokazano wyrównanie tekstu za pomocą omawianych atrybutów:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wyrównanie tekstu
Tekst wyrównany do lewej strony
Tekst wyśrodkowany
Tekst wyrównany do prawej strony
Nie zawijany tekst w długim wierszu...
Na rysunku 12.7 pokazano ten dokument w przeglądarce. Rysunek 12.7. Wyrównywanie tekstu w dokumencie WML Podstawowe formatowanie tekstu W WML obsługiwane są także niektóre elementy formatujące tekstu odziedziczone po HTML, takie jak do pogrubienia, do kursywy czy do podkreślenia. Oto przykład ich zastosowania (pamiętaj jednak, że nie wszystkie mikroprzeglądarki obsługują te elementy):
2 Jak widać w pasku tytułu, przeglądarka ta nie zawsze dobrze sobie radzi z polskimi literami. (przyp. tłum.) D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 25 26 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) "http://www.wapforum.org/DTD/wml_1.1.xml">
Formatowanie tekstu
W WML obsługiwane są następujące sposoby formatowania tekstu: pogrubienie, powiększenie, zaakcentowanie, kursywa, zmniejszenie, wyróżnienie oraz podkreślenie.
Wynik w przeglądarce pokazano na rysunku 12.8. Rysunek 12.8. Formatowanie tekstu w WML Przyciski W WML przyciski tworzy się za pomocą elementu do. Załóżmy na przykład, że chcemy umożliwić użytkownikowi dokumentu WML przejście na stronę www.starpowder.com/planets.wml. Zaczniemy od elementu do, przypiszemy mu atrybut type o wartości accept i dodamy etykietę za pomocą atrybutu label:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Przyciski
. . .
Do przejścia do nowego dokumentu służy element go, w którym w atrybucie href podaje się docelowy adres URI:
Na rysunku pokazano wynik naszej pracy pojawił się przycisk. Jego kliknięcie spowoduje skok pod adres www.starpowder.com/planets.wml. Rysunek 12.9. Wyświetlanie w dokumencie WML przycisku Jak już wcześniej wspomniano, w talii może znajdować się wiele kart, ale zawsze jest widoczna tylko jedna na raz. Jak zatem dostać się do pozostałych? Używa się do tego przycisków. W tym wypadku atrybutowi href elementu go przypisujesz identyfikator karty docelowej. Oto przykład, gdzie mamy dwie karty i przycisk umożliwiający użytkownikowi nawigację z pierwszej karty do drugiej:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wiele kart
To jest karta 2.
Wynik pokazano na rysunku 12.10. Kiedy użytkownik kliknie przycisk, przeglądarka przeskoczy na drugą kartę z talii. Tak właśnie można się poruszać między kartami w WML. Rysunek 12.10. Wyświetlanie w dokumencie WML przycisku nawigacyjnego Jak teraz użytkownik ma się dostać z powrotem z karty 2 na kartę 1? To właśnie temat następnego punktu. Przycisk Wstecz W WML obsługiwany jest specjalny przycisk, który jest bardzo często wyświetlany Wstecz. Aby taki przycisk dodać do drugiej karty, użyjemy elementu prev:
"http://www.wapforum.org/DTD/wml_1.1.xml"> D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 27 28 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony)
Wiele kart
To jest karta 2.
I to już wystarczy. Jak widać na rysunku 12.11, na drugiej karcie pojawił się przycisk Wstecz. Kiedy użytkownik go kliknie, przeglądarka przeskoczy na poprzednią kartę. Pamiętaj, że użytkownik używa przycisków do poruszania się między kartami talii, więc wskazane jest umieszczenie przycisku Wstecz na każdej karcie (mikroprzeglądarki zwykle nie mają wbudowanego przycisku Wstecz czy Back, który istnieje w Klondike). Rysunek 12.11. Wyświetlanie przycisku Wstecz Hiperłącza W WML obsługiwany jest także element a umożliwiający tworzenie hiperłączy. Tak jak w HTML, tak i tu docelowy adres podawany jest w atrybucie href. Oto przykład, w którym hiperłącze zawiedzie użytkownika do przykładu firmy Apache:
Na rysunku 12.12 pokazano wynik; kiedy użytkownik kliknie hiperłącze, przeglądarka przeniesie go pod wskazany adres. 28 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) Rysunek 12.12. Hiperłącze WML Tabele Tabele w WML tworzy się za pomocą znanych z HTML elementów table, tr i td (nie istnieją natomiast th, tbody, thead ani tfoot). Zwróć uwagę, jak bardzo poniższy przykład przypomina tabelę HTML:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Tabele
TIC
TAC
TOE
x
o
x
o
x
o
x
o
x
Na rysunku 12.13 pokazano wynik. Rysunek 12.13. Tabele WML D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 29 30 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) Wprowadzanie danych tekstowych W WML obsługiwany jest także element input. Jeśli jego atrybutowi type nadasz wartość text, wyświetlone zostanie pole tekstowe, takiej jak pola znane z HTML (jednak nie wszystkie mikroprzeglądarki są w stanie ten element obsłużyć). W poniższym przykładzie umożliwimy użytkownikowi podać nazwę pliku lokalnego w polu tekstowym. Kiedy użytkownik kliknie przycisk Skocz, przeglądarka wyświetli podany plik. Zaczniemy od utworzenia pola tekstowego:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wprowadzanie tekstu
Skocz pod adres:
. . .
Kiedy użytkownik kliknie przycisk Skocz, będziemy musieli jakoś odczytać tekst z pola uri. Do wartości pola tekstowego można się odwołać stosując zapis $(uri):
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wprowadzanie tekstu
Skocz pod adres:
Na rysunku 12.14 pokazano wyniki. Kiedy użytkownik w polu tekstowym poda adres dokumentu lokalnego i kliknie przycisk Skocz, przeglądarka odczyta nazwę dokumentu i go otworzy. Rysunek 12.14. Obsługa wprowadzania tekstu Niejako przy okazji zetknęliśmy się tu z pojęciem zmiennych WML, w tym przypadku $(uri). Możliwość bezpośredniej obsługi zmiennych czyni z WML język nie tylko znacznikowy, ale też 30 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc Rozdział 1 f& Pierwsze kroki (Nagłówek strony) zawierający pewne funkcje skryptowe. Istnieje też element setvar, który umożliwia przypisywanie zmiennym wartości: W następnym punkcie zajmiemy się zmiennymi dokładniej. Listy wyboru Tak jak w HTML, tak i w WML obsługiwany jest element select tworzący kontrolkę wyboru (działającą jak lista rozwijalna). W ramach przykładu taką kontrolkę utworzymy teraz. Kiedy po dokonaniu już wyboru użytkownik kliknie przycisk Odczyt wyboru, zostanie przeniesiony na nową kartę, która dokonany wybór pokaże. Zaczniemy od zdefiniowania kontrolki i nadania jej nazwy selection:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wybór
Tak jak w HTML, poszczególne opcje podajemy stosując element option:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wybór
. . . Następnie dodajemy przycisk Odczyt wyboru, którego kliknięcie spowoduje przejście do następnej karty, karty 2:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wybór
. D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 31 32 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony) . . Na karcie 2 wyświetlimy wartość kontrolki wyboru, do której odwołamy się stosując zapis $(selection). Wartość ta jest napisem z atrybutu value aktualnie wybranego elementu option. Na karcie 2 wyświetlimy dokonany wybór:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Wybór
Wybrano $(selection).
Na rysunku 12.15 pokazano naszą talię w działaniu wybrano Szpinak. Rysunek 12.15. Wybieranie wartości Kliknięcie przycisku Odczyt wyboru powoduje przejście do karty 2, na której pokazywany jest wybór dokonany przez użytkownika rysunek 12.16. Rysunek 12.16. Informowanie o dokonanym wyborze Inną użyteczną możliwością zastosowania kontrolek wyboru jest użycie atrybutu onpick elementów option, co umożliwia przenoszenie się pod inne adresy URI kiedy tylko użytkownik wybierze jakąś opcję. Oto przykład wystarczy ustawić wartość atrybut onpick poszczególnych elementów option na adresy URI; kiedy użytkownik wybierze jeden z nich, przeglądarka przeskoczy pod wskazany adres:
Użycie zegara W WML można użyć zegara do odmierzenia zadanego czasu, a przeglądarka po upływie tego okresu automatycznie coś wykona. Jeśli na przykład atrybutowi ontimer karty przypiszemy identyfikator innej karty, to przeglądarka po upływie zadanego czasu przejdzie do karty docelowej:
"http://www.wapforum.org/DTD/wml_1.1.xml"> . . .
. . . Zegar tworzy się stosując element timer i przypisując mu okres czasu w atrybucie value (miarą jest dziesiąta część sekundy). Nasz zegar ustawimy na 10 sekund:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Użycie zegara
W ciągu dziesięciu sekund zostanie przeniesiony na drugą kartę.
. . . Teraz należy dodać tę drugą kartę:
"http://www.wapforum.org/DTD/wml_1.1.xml"> D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 33 34 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony)
Użycie zegara
W ciągu dziesięciu sekund zostanie przeniesiony na drugą kartę.
Witaj na karcie 2.
Kiedy otwierasz tę talię, wyświetlana jest karta 1, co pokazano na rysunku 12.17. Po dziesięciu sekundach przeglądarka przełącza się na kartę 2. W przeglądarce Klondike upływ czasu jest pokazywany w prawym dolnym rogu, w okienku Timer; na rysunku widać, że do przełączenia zostało jeszcze 7 sekund. Rysunek 12.17. Użycie zegara Aączenie się z serwerem W WML można tworzyć formularze, które są bardzo podobne w działaniu do formularzy HTML. Dane formularza WML są tak samo kodowane, można je zatem przekazać do skryptu CGI (jednak trzeba pamiętać, że nie wszystkie przeglądarki formularze obsługują). W poniższym przykładzie prosimy użytkowników o ich komentarze, które przekazujemy do skryptu CGI o nazwie comments.cgi. Na początek tworzymy przycisk z etykietą Aadowanie danych, jego atrybut method ustawiamy na post, zaś href na adres, pod który dane mają być wysyłane, tutaj http://www.starpowder.com/comments.cgi zupełnie jak w HTML:
. . . Teraz trzeba tylko wskazać ładowane dane i dane te nazwać. Używa się do tego atrybutów name i value elementu postfield. W tym wypadku ładować będziemy tekst z pola comments:
To już wystarczy. Skrypt CGI może odczytać załadowane dane tak, jak odczytałby je z dokumentu HTML. Zwróć uwagę, że podczas odsyłania odpowiedzi dane należy sformatować jako WML, a w nagłówku HTTP jako typ MIME podać text/vnd.wap.wml. Obrazki W WML można wyświetlać obrazki, ale jest tu pewna pułapka: wszystkie te obrazki muszą być w specjalnym formacie WBMP, a ten format nie pozwala uzyskać takiej głębi kolorów, do jakiej przywykłeś. Tak naprawdę WBMP jest formatem czarno białym bez żadnej skali szarości jeden bit na piksel. Pod adresami z poniższej listy znajdziesz nieco informacji i programów do obsługi WBMP: " www.creationflux.com/laurent/wbmp.html. Wtyczka (plug-in) do Photoshopa Adobe pozwalająca tworzyć pliki WBMP. " www.gingco.de/wap/content/download.html. Gotowy do pobrania konwerter obrazków pozwalający uzyskać format WBMP. " www.phnet.fi/public/jiikoo/ Przydatny program do rysowania w formacie WBMP o nazwie WAPDraw. " www.teraflops.com/wbmp. Konwerter działający za pośrednictwem Internetu, umożliwia proste konwertowanie obrazków na format WBMP. Uzyskane obrazki można pobrać dowolną przeglądarką, byle nie rozumiała tego formatu, gdyż wtedy obrazek zostanie po prostu wyświetlony. Aby wyświetlić obrazek, używa się elementu img chyba nie jesteś zaskoczony? Ustawia się atrybuty alt, src, width i height, jak w poniższym przykładzie:
"http://www.wapforum.org/DTD/wml_1.1.xml">
Obrazki
src="twarz.wbmp" width="164" height="164"/>
D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc 35 36 Część I f& Podstawy obsługi systemu WhizBang (Nagłówek strony)
Na rysunku 12.18 pokazano dokument WML wraz z obrazkiem WBMP. Rysunek 12.18. Wyświetlanie obrazka I tak oto kończymy poznawanie WML, a także XML. W trakcie czytania tej książki poznałeś naprawdę wiele tematów związanych z XML, od podstawowych jak składnia XML po zaawansowane, jak programowa obsługa dokumentów, poznałeś też różne aplikacje XML, na przykład VML czy WML. Teraz zostało Ci już tylko jedno: zaprząc tę niezwykłą technologię, aby pracowała na Twoje potrzeby. 36 D:\Kompakt !!!\Kompakt\Ksiazki\XML Vademecum profesjonalisty\r12-01.doc